ca證書demo與相關問題

以下是CA證書的工具類

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.Signature;
import java.security.SignatureException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import sun.misc.BASE64Encoder;
import sun.security.x509.AlgorithmId;
import sun.security.x509.CertAndKeyGen;
import sun.security.x509.CertificateAlgorithmId;
import sun.security.x509.CertificateSerialNumber;
import sun.security.x509.CertificateValidity;
import sun.security.x509.CertificateVersion;
import sun.security.x509.CertificateX509Key;
import sun.security.x509.X500Name;
import sun.security.x509.X500Signer;
import sun.security.x509.X509CertImpl;
import sun.security.x509.X509CertInfo;

import com.inner.game.util.BASE64;

/**
 * 首先生成CA的根證書,然後有CA的根證書籤署生成linkSDK001的證書
 * 
 * @author pfx
 */
public class GenX509Cert {

	/** 提供強加密隨機數生成器 (RNG)* */
	private SecureRandom sr;
	private String userprivKey;
	private String publickey;
	private String serPublicKey;
	private String serPrivateKey;
	private String serCert;

	static {
		try {
			Security.addProvider(new BouncyCastleProvider());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public GenX509Cert() throws NoSuchAlgorithmException,
			NoSuchProviderException {
		// 返回實現指定隨機數生成器 (RNG) 算法的 SecureRandom 對象。
		sr = SecureRandom.getInstance("SHA1PRNG", "SUN");
	}

	/**
	 * 生成證書
	 * 
	 * @param certificate
	 * @param rootPrivKey
	 * @param kp
	 * @param subInfo
	 * @param subAlias
	 * @param subPwd
	 * @param subFilepath
	 * @return
	 * @throws CertificateException
	 * @throws IOException
	 * @throws InvalidKeyException
	 * @throws NoSuchAlgorithmException
	 * @throws NoSuchProviderException
	 * @throws SignatureException
	 */
	public boolean createCert(X509Certificate certificate,
			PrivateKey rootPrivKey, KeyPair kp, String subInfo,
			String subAlias, String subPwd, String subFilepath, String filename)
			throws CertificateException, IOException, InvalidKeyException,
			NoSuchAlgorithmException, NoSuchProviderException,
			SignatureException {

		// X.509 v1 證書的抽象類。此類提供了一種訪問 X.509 v1 證書所有屬性的標準方式。
		byte certbytes[] = certificate.getEncoded();
		// The X509CertImpl class represents an X.509 certificate.
		X509CertImpl x509certimpl = new X509CertImpl(certbytes);
		// The X509CertInfo class represents X.509 certificate information.
		X509CertInfo x509certinfo = (X509CertInfo) x509certimpl
				.get("x509.info");
		// This class defines the X509Key attribute for the Certificate.
		x509certinfo.set("key", new CertificateX509Key(kp.getPublic()));
		// 設置issuer域 "CN=RootCA,OU=hackwp,O=wp,L=BJ,S=BJ,C=CN"
		X500Name issuer = new X500Name(certificate.getIssuerDN().getName());
		x509certinfo.set("issuer.dname", issuer);
		// 2253 style). "CN=scriptx, OU=wps, O=wps, L=BJ, ST=BJ, C=CN"
		X500Name subject = new X500Name(subInfo);
		x509certinfo.set("subject.dname", subject);
		// 此 Signature 類用來爲應用程序提供數字簽名算法功能。返回實現指定簽名算法的 Signature 對象。
		Signature signature = Signature.getInstance("MD5WithRSA");
		// 初始化這個用於簽名的對象。如果使用其他參數再次調用此方法,此調用的結果將無效。
		signature.initSign(kp.getPrivate());
		// This class provides a binding between a Signature object and an
		// authenticated X.500 name (from an X.509 certificate chain), which is
		// needed in many public key signing applications.
		X500Signer signer = new X500Signer(signature, issuer);
		// This class identifies algorithms, such as cryptographic transforms,
		// each of which may be associated with parameters.
		AlgorithmId algorithmid = signer.getAlgorithmId();
		// This class defines the AlgorithmId for the Certificate.
		x509certinfo
				.set("algorithmID", new CertificateAlgorithmId(algorithmid));
		// 開始時間
		Date bdate = new Date();
		// 結束時間
		Date edate = new Date();
		// 天 小時 分 秒 毫秒
		edate.setTime(bdate.getTime() + 3650 * 24L * 60L * 60L * 1000L);
		// validity爲有效時間長度 單位爲秒,This class defines the interval for which the
		// certificate is valid.證書的有效時間
		CertificateValidity certificatevalidity = new CertificateValidity(
				bdate, edate);
		x509certinfo.set("validity", certificatevalidity);
		// This class defines the SerialNumber attribute for the Certificate.
		// 設置有效期域(包含開始時間和到期時間)域名等同與x509certinfo.VALIDITY
		x509certinfo.set("serialNumber", new CertificateSerialNumber(
				(int) (new Date().getTime() / 1000L)));
		// 設置序列號域,This class defines the version of the X509 Certificate.
		CertificateVersion cv = new CertificateVersion(CertificateVersion.V3);
		x509certinfo.set(X509CertInfo.VERSION, cv);
		// 設置版本號 只有v1 ,v2,v3這幾個合法值

		X509CertImpl x509certimpl1 = new X509CertImpl(x509certinfo);

		x509certimpl1.sign(rootPrivKey, "MD5WithRSA");
		// 使用另一個證書的私鑰來簽名此證書 這裏使用 md5散列 用rsa來加密

		// BASE64Encoder base64 = new BASE64Encoder();

		// FileOutputStream fos = new FileOutputStream(new File(subFilepath
		// + filename + ".crt"));
		// // base64.encodeBuffer(x509certimpl1.getEncoded(), fos);
		// String str = "-----BEGIN CERTIFICATE-----\r\n"
		// + base64.encode(x509certimpl1.getEncoded())
		// + "\r\n-----END CERTIFICATE-----";
		// fos.write(str.getBytes());
		// fos.flush();
		// fos.close();

		try {
			Certificate[] certChain = { x509certimpl1 };

			// savePfx("scriptx", kp.getPrivate(), "123456", certChain,
			// "C:\\lzj\\tmp\\cer\\ca\\ScriptX.jks");

			savePfx(subAlias, kp.getPrivate(), subPwd, certChain, subFilepath
					+ filename + ".pfx");

			// saveJks(subAlias, kp.getPrivate(), subPwd, certChain, subFilepath
			// + filename + ".jks");

			// FileInputStream in = new FileInputStream(subFilepath + filename
			// + ".jks");
			FileInputStream in = new FileInputStream(subFilepath + filename
					+ ".pfx");
			FileInputStream newin = new FileInputStream(subFilepath + filename
					+ ".pfx");
			// FileInputStream newin = new FileInputStream(subFilepath +
			// filename
			// + ".jks");

			ByteArrayOutputStream out = new ByteArrayOutputStream();
			byte[] buffer = new byte[newin.available()];
			newin.read(buffer);
			out.write(buffer);
			// KeyStore inputKeyStore = KeyStore.getInstance("jks");
			KeyStore inputKeyStore = KeyStore.getInstance("pkcs12", "BC");
			inputKeyStore.getProvider().getName();
			inputKeyStore.load(in, subPwd.toCharArray());
			PrivateKey privk = (PrivateKey) inputKeyStore.getKey(subAlias,
					subPwd.toCharArray());
			String key = BASE64.encode(privk.getEncoded());
			// FileOutputStream privKfos = new FileOutputStream(new File(
			// subFilepath + filename + ".pvk"));
			//
			// privKfos.write(privk.getEncoded());

			userprivKey = BASE64.encode(buffer);
			publickey = BASE64
					.encode(x509certimpl1.getPublicKey().getEncoded());
			System.out.println("publickey = " + publickey);
			System.out.println("userprivKey = " + userprivKey);
			System.out.println("key = " + key);
			// System.out.println("userprivKey = " + new String(buffer));
			// base64.encode(key.getEncoded(), privKfos);
			newin.close();
			in.close();
			// 生成文件
			x509certimpl1.verify(certificate.getPublicKey(), null);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}

	}

	/**
	 * 保存此根證書信息KeyStore Personal Information Exchange
	 * 
	 * @param alias
	 * @param privKey
	 * @param pwd
	 * @param certChain
	 * @param filepath
	 * @throws Exception
	 */
	public void savePfx(String alias, PrivateKey privKey, String pwd,
			Certificate[] certChain, String filepath) throws Exception {

		Security
				.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
		KeyStore outputKeyStore = KeyStore.getInstance("pkcs12", "BC");
		outputKeyStore.load(null, pwd.toCharArray());
		System.out.println(outputKeyStore.getProvider().getInfo());
		outputKeyStore
				.setKeyEntry(alias, privKey, pwd.toCharArray(), certChain);
		FileOutputStream out = new FileOutputStream(filepath);
		// 將此 keystore 存儲到給定輸出流,並用給定密碼保護其完整性。
		System.out.println(outputKeyStore.getKey(alias, pwd.toCharArray()));
		outputKeyStore.store(out, pwd.toCharArray());
		out.close();
	}

	/**
	 * 生成jks文件
	 * 
	 * @param alias
	 * @param privKey
	 * @param pwd
	 * @param certChain
	 * @param filepath
	 * @throws Exception
	 */
	public void saveJks(String alias, PrivateKey privKey, String pwd,
			Certificate[] certChain, String filepath) throws Exception {

		KeyStore outputKeyStore = KeyStore.getInstance("jks");
		outputKeyStore.load(null, pwd.toCharArray());

		outputKeyStore
				.setKeyEntry(alias, privKey, pwd.toCharArray(), certChain);

		FileOutputStream out = new FileOutputStream(filepath);
		outputKeyStore.store(out, pwd.toCharArray());
		out.close();
	}

	/**
	 * 頒佈根證書,自己作爲CA
	 * 
	 * @param subInfo
	 * @param alias
	 * @param pwd
	 * @param filepath
	 * @throws NoSuchAlgorithmException
	 * @throws NoSuchProviderException
	 * @throws InvalidKeyException
	 * @throws IOException
	 * @throws CertificateException
	 * @throws SignatureException
	 * @throws UnrecoverableKeyException
	 */
	public void createRootCA(String caInfo, String alias, String pwd,
			String filepath) throws NoSuchAlgorithmException,
			NoSuchProviderException, InvalidKeyException, IOException,
			CertificateException, SignatureException, UnrecoverableKeyException {

		CertAndKeyGen cak = new CertAndKeyGen("RSA", "MD5WithRSA", null);
		cak.setRandom(sr);
		cak.generate(1024);
		BASE64Encoder base64 = new BASE64Encoder();
		// byte[] key1 = cak.getPublicKey().getEncoded();
		// String pri1 = BASE64.encode(key1);
		// "CN=RootCA,OU=hackwp,O=wp,L=BJ,S=BJ,C=CN"
		X500Name subject = new X500Name(caInfo);
		// 自簽名的根證書
		X509Certificate certificate = cak.getSelfCertificate(subject,
				3650 * 24L * 60L * 60L);
		// X509Certificate certificate = cak.getSelfCertificate(subject,
		// new Date(), 3650 * 24L * 60L * 60L);

		X509Certificate[] certs = { certificate };
		try {
			// savePfx("RootCA", cak.getPrivateKey(), "123456", certs,
			// "C:\\lzj\\tmp\\cer\\ca\\RootCa.pfx");
			saveJks(alias, cak.getPrivateKey(), pwd, certs, filepath
					+ "RootCa.jks");
		} catch (Exception e) {
			e.printStackTrace();
			return;
		}
		// 後一個long型參數代表從現在開始的有效期 單位爲秒(如果不想從現在開始算 可以在後面改這個域)
		FileOutputStream fos = new FileOutputStream(new File(filepath
				+ "RootCa.crt"));
		// 添加證書前和後標記
		// base64.encodeBuffer(certificate.getEncoded(), fos);

		String str = "-----BEGIN CERTIFICATE-----\r\n"
				+ base64.encode(certificate.getEncoded())
				+ "\r\n-----END CERTIFICATE-----";
//		System.out.println("ca證書:start------" );
		serCert = base64.encode(certificate.getEncoded());
//		System.out.println( base64.encode(certificate.getEncoded()));
//		System.out.println("ca證書:end------" );
		fos.write(str.getBytes());
		fos.flush();
		fos.close();
		serPrivateKey = BASE64.encode(cak.getPrivateKey().getEncoded());
		serPublicKey = BASE64.encode(certificate.getPublicKey().getEncoded());
		System.out.println("serPrivateKey = " + serPrivateKey);
		System.out.println("serPublicKey = " + serPublicKey);
	}

	public boolean signCert(String alias, String pwd, String filepath,
			String subInfo, String subAlias, String subPwd, String subFilepath,
			String filename) throws NoSuchAlgorithmException,
			CertificateException, IOException, UnrecoverableKeyException,
			InvalidKeyException, NoSuchProviderException, SignatureException {

		try {
			// KeyStore ks = KeyStore.getInstance("pkcs12");
			// FileInputStream ksfis = new
			// FileInputStream("C:\\lzj\\tmp\\cer\\ca\\RootCa.pfx");
			KeyStore ks = KeyStore.getInstance("jks");
			FileInputStream ksfis = new FileInputStream(filepath + "RootCa.jks");
			char[] storePwd = pwd.toCharArray();
			char[] keyPwd = pwd.toCharArray();
			// 從給定輸入流中加載此 KeyStore。
			ks.load(ksfis, storePwd);

			ksfis.close();

			// 返回與給定別名關聯的密鑰(私鑰),並用給定密碼來恢復它。必須已經通過調用 setKeyEntry,或者以
			// PrivateKeyEntry
			// 或 SecretKeyEntry 爲參數的 setEntry 關聯密鑰與別名。
			PrivateKey privK = (PrivateKey) ks.getKey(alias, keyPwd);
			// 返回與給定別名關聯的證書。如果給定的別名標識通過調用 setCertificateEntry 創建的條目,或者通過調用以
			// TrustedCertificateEntry 爲參數的 setEntry
			// 創建的條目,則返回包含在該條目中的可信證書。如果給定的別名標識通過調用 setKeyEntry 創建的條目,或者通過調用以
			// PrivateKeyEntry 爲參數的 setEntry 創建的條目,則返回該條目中證書鏈的第一個元素。
			X509Certificate certificate = (X509Certificate) ks
					.getCertificate(alias);

			return createCert(certificate, privK, genKey(), subInfo, subAlias,
					subPwd, subFilepath, filename);
		} catch (KeyStoreException e) {
			e.printStackTrace();
			return false;
		}
	}

	public KeyPair genKey() throws NoSuchAlgorithmException {
		KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
		kpg.initialize(1024, sr);
		KeyPair kp = kpg.generateKeyPair();
		return kp;
	}

	// public static void main(String[] args) {
	//
	// try {
	// GenX509Cert gcert = new GenX509Cert();
	// /*
	// * 創建ca證書,該操作只需只需一次,執行條件是更換服務器證書時,有效期10年。
	// *
	// * 運行環境:jdk1.6
	// *
	// * 參數說明: caInfo --指定證書擁有者信息,本例中可以不用修改,分別表示: ? OU(Organization Unit -
	// * 組織單位名稱) ? O(Organization - 組織名稱) ? L(Locality - 城市或區域名稱) ?
	// * ST(State - 州或省份名稱) ? C(Country - 國家名稱) caAlias
	// * --產生別名,用RootCA就可以,不用變。 caPwd --指定別名條目的密碼,本例中該密碼同時也是jks密碼
	// * caFilepath --證書保存路徑,運行後將在該路徑中生成【RootCa.jks】【RootCa.crt】兩個文件,
	// * 文件說明: 其中【RootCa.jks】用於部署應用服務器的https服務時用
	// * 其中【RootCa.crt】文件用於預埋在客戶端中,驗證服務器證書用。
	// */
	// String caInfo = "CN=RootCA,OU=Linktech,O=Link,L=SY,S=LN,C=CN";
	// String caAlias = "RootCA";
	// String caPwd = "Link@1234";
	// // String caFilepath = "C:\\lzj\\tmp\\cer\\ca\\ca2\\";
	// String caFilepath = "D:/linshi/";
	// // gcert.createRootCA(caInfo, caAlias, caPwd, caFilepath);
	//
	// // System.out.println("createRootCA完畢");
	//
	// /*
	// * 生成用戶證書,該操作是用來申請用戶證書時用,每次申請證書時調用1次,該證書有效期10年,根據需要可以調整。
	// *
	// * 運行環境:jdk1.6
	// *
	// * 參數說明: subInfo --指定證書擁有者信息,含義同上。本例中用手機號表示相關信息 subAlias
	// * --產生別名,建議用用戶手機號 subPwd --指定別名條目的密碼,本例中該密碼同時也是jks密碼,該密需要通知客戶端程序。
	// * subFilepath
	// * --證書保存路徑,運行後將在該路徑中生成【15940163439.jks】【15940163439.crt】
	// * 【15940163439.pvk】三個文件, 文件說明:
	// * 【15940163439.jks】密鑰倉庫,該文件可以根據需要傳給客戶端程序,客戶端需要利用subPwd這個密碼導出私鑰,
	// * 並利用私鑰對數據進行簽名。 【15940163439.crt】本例中暫時無用處
	// * 【15940163439.pvk】私鑰文件,該文件可以根據需要傳給客戶端程序,客戶端可以利用該文件對數據進行簽名。
	// *
	// * 上述文件主要是針對java生成的jks(keystore),如果客戶端想要pkcs12格式證書,需要修改部分程序實現。
	// */
	// String subInfo = "CN=15940163439,OU=user,O=SDK,L=SY,S=LN,C=CN";
	// String subAlias = "15940163439";
	// String subPwd = "15940163439";
	// gcert.getUserCert(subInfo, subAlias);
	// // String subFilepath = "C:\\lzj\\tmp\\cer\\ca\\ca2\\";
	// String subFilepath = "D:/linshi/";
	//
	// // gcert.signCert(caAlias, caPwd, caFilepath, subInfo, subAlias,
	// // subPwd, subFilepath);
	// System.out.println("signCert完畢");
	//
	// } catch (Exception e) {
	// e.printStackTrace();
	// }
	// }

	public static void main(String[] args) throws Exception {
		GenX509Cert gen = new GenX509Cert();
		String serverCert = gen.getServerCert();
		System.out.println(serverCert);
//		gen.getUserCert("460010304607431869625000040505");

		// KeyStore ks = KeyStore.getInstance("jks");
		// FileInputStream ksfis = new FileInputStream("D:/linshi/" +
		// "460010304607431869625000040505.jks");
		// char[] storePwd = "SHELLNDK!@#0".toCharArray();
		// char[] keyPwd = "SHELLNDK!@#0".toCharArray();
		// // 從給定輸入流中加載此 KeyStore。
		// ks.load(ksfis, storePwd);
		//
		// ksfis.close();

		// 返回與給定別名關聯的密鑰(私鑰),並用給定密碼來恢復它。必須已經通過調用 setKeyEntry,或者以
		// PrivateKeyEntry
		// 或 SecretKeyEntry 爲參數的 setEntry 關聯密鑰與別名。
		// PrivateKey privK = (PrivateKey) ks.getKey("USER#CERT%v1", keyPwd);
		// System.out.println(BASE64.encode(privK.getEncoded()));
	}

	public Map<String, Object> getUserCert(String filename) {
		Map<String, Object> map = new HashMap<String, Object>();
		InputStream in = GenX509Cert.class.getClassLoader()
				.getResourceAsStream("ca.properties");
		Properties config = new Properties();
		try {
			config.load(in);
			in.close();
		} catch (IOException e) {
			map.put("resultCode", "1011");
			map.put("resultmsg", "解析ca配置文件失敗");
			return map;
		}

		// 獲取apk信息
		String caAlias = config.getProperty("caAlias");
		String caPwd = config.getProperty("caPwd");
		String caFilepath = config.getProperty("caFilepath");

		String subFilepath = config.getProperty("subFilepath");
		String subInfo = config.getProperty("subInfo");
		String subPwd = config.getProperty("userPwd");
		String subAlias = config.getProperty("subAlias");

		try {
			signCert(caAlias, caPwd, caFilepath, subInfo, subAlias, subPwd,
					subFilepath, filename);
			System.out.println("signCert完畢");
		} catch (Exception e) {
			e.printStackTrace();
			map.put("resultCode", "1012");
			map.put("resultmsg", "生成用戶證書失敗");
			return map;
		}
		map.put("resultCode", "0");
		map.put("userPublicKey", publickey);
		map.put("userCert", userprivKey);
		return map;
	}

	
	public String getServerCert() {
		/*
		 * 創建ca證書,該操作只需只需一次,執行條件是更換服務器證書時,有效期10年。
		 * 
		 * 運行環境:jdk1.6
		 * 
		 * 參數說明: caInfo --指定證書擁有者信息,本例中可以不用修改,分別表示: ? OU(Organization Unit -
		 * 組織單位名稱) ? O(Organization - 組織名稱) ? L(Locality - 城市或區域名稱) ? ST(State -
		 * 州或省份名稱) ? C(Country - 國家名稱) caAlias --產生別名,用RootCA就可以,不用變。 caPwd
		 * --指定別名條目的密碼,本例中該密碼同時也是jks密碼 caFilepath
		 * --證書保存路徑,運行後將在該路徑中生成【RootCa.jks】【RootCa.crt】兩個文件, 文件說明:
		 * 其中【RootCa.jks】用於部署應用服務器的https服務時用 其中【RootCa.crt】文件用於預埋在客戶端中,驗證服務器證書用。
		 */
		Map<String, Object> map = new HashMap<String, Object>();
		InputStream in = GenX509Cert.class.getClassLoader()
				.getResourceAsStream("ca.properties");
		Properties config = new Properties();
		try {
			config.load(in);
			in.close();
		} catch (IOException e) {
			map.put("resultCode", "1011");
			System.out.println("解析ca配置文件失敗");
			return "1011";
		}
		String caAlias = config.getProperty("caAlias");
		String caPwd = config.getProperty("caPwd");
		String caFilepath = config.getProperty("caFilepath");
		String caInfo = config.getProperty("subInfo");
		// 生成rootCA證書
		try {
			createRootCA(caInfo, caAlias, caPwd, caFilepath);
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("生成CA證書失敗!");
			return "1012";
		}

		System.out.println("createRootCA完畢");
		return serCert;
	}
}


配置文件:ca.properties

subInfo=CN\=userCert,OU\=user,O\=SDK,L\=SY,S\=LN,C\=CN
caAlias=RootCA
caPwd=Link@1234
#caFilepath=/home/weblogic/Oracle/Middleware/user_projects/domains/shu00/
#subFilepath=/home/weblogic/Oracle/Middleware/user_projects/domains/app/pfx/
#caFilepath=/home/weblogic/Oracle/Middleware/user_projects/domains/SDK/
#subFilepath=/home/weblogic/Oracle/Middleware/user_projects/domains/SDK/pfx/
caFilepath=F:/
subFilepath=F:/
subAlias=USER\#CERT%v1
userPwd=SHELLNDK\!@\#0

調用main函數會生產服務器的證書,調用getUserCert方法生產用戶證書。

在生成用戶證書時可能會出現錯誤:

java.security.InvalidKeyException: Illegal key size or default parameters

原因:

Java幾乎各種常用加密算法都能找到對應的實現。因爲美國的出口限制,Sun通過權限文件(local_policy.jar、US_export_policy.jar)做了相應限制。因此存在一些問題:
●密鑰長度上不能滿足需求(如:java.security.InvalidKeyException: Illegal key size or default parameters);
●部分算法未能支持,如MD4、SHA-224等算法;
●API使用起來還不是很方便;一些常用的進制轉換輔助工具未能提供,如Base64編碼轉換、十六進制編碼轉換等工具。
解決辦法:
Oracle在其官方網站上提供了無政策限制權限文件(Unlimited Strength Jurisdiction Policy Files),我們只需要將其部署在JRE環境中,就可以解決限制問題。
文件位於${java_home}/jre/lib/security 
所以下載匹配的jce_policy ,替換jdk安裝目錄下 jdk1.* \jre\lib\security 中的 local_policy.jar  和 US_export_policy.jar 兩個jar包

Java 5.0 無政策限制文件:http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java-plat-419418.html#jce_policy-1.5.0-oth-JPR

Java 6 無政策限制文件:http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html
Java 7 無政策限制文件:http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
其他版本 無政策限制文件:http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java-plat-419418.html


注意事項:

1.生成證書類依賴jdk1.6的rt.jar

2.配置tomcat server.xml   

<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
               maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS" keystoreFile="RootCa.jks的路徑"  keystorePass="生成時的密碼"  />



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章