網上大多數文章都是用keytool生成自簽名根證書,將根證書配置在tomcat的server.xml中。我不太喜歡用keytool,原因:
1.我們可能換provider,不同的provider會有不同的算法實現,算法的安全性和性能也可能不同,通過代碼生成比較方便一些,不同算法的實現要放在classpath上。
2.通過代碼生成還有一個好處,會對整個流程理解的比較清楚,實現的原理到底是怎樣的。
要用到https,也就是TLS或者SSL,我們需要有證書,要么是法定證書機構(VeriSign,中國估計也有代理)給你簽發的可信證書,要么自己給自己頒發一個根證書。自己給自己頒發的證書,瀏覽器是不信任的,會彈出一個提示框。
SSL認證分為雙向認證和單向認證(客戶端認證服務器),一般做網站單向認證就可,客戶端要認證服務器端的證書,認證通過,通過非對稱加密算法交換秘密密鑰,以后的通信數據通過秘密密鑰加密。
所以說要想用https,就得現有證書。有證書就得現有公私鑰。
public static KeyPair generateKeyPair() throws NoSuchAlgorithmException,
NoSuchProviderException {
// create the keys
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(1024, new SecureRandom());
return generator.generateKeyPair();
}
|
有了公私鑰,接著就生成證書。
public static X509Certificate generateX509V3RootCertificate(KeyPair pair)
throws NoSuchAlgorithmException, NoSuchProviderException,
CertificateEncodingException, InvalidKeyException,
IllegalStateException, SignatureException {
X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
certGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
certGen.setIssuerDN(new X500Principal(
"CN=localhost, OU=Ldd600 Blog, O=SHA, C=cn"));
certGen.setNotBefore(new Date(System.currentTimeMillis() - 5000L));
certGen.setSubjectDN(new X500Principal(
"CN=localhost, OU=Ldd600 Blog, O=SHA, C=cn"));
certGen.setPublicKey(pair.getPublic());
certGen.setSignatureAlgorithm("SHA1WithRSA");
certGen.setNotAfter(new Date(System.currentTimeMillis()
+ Integer.MAX_VALUE));
return certGen.generate(pair.getPrivate(), new SecureRandom());
}
public static X500PrivateCredential createRootCredential(KeyPair rootPair)
throws Exception {
X509Certificate rootCert =
generateX509V3RootCertificate(rootPair);
return new X500PrivateCredential(rootCert, rootPair.getPrivate());
}
|
有了證書,我們要將證書存儲起來,根證書是自簽名的證書,凡是通過根證書簽名頒發的證書都是可信任的。根證書需要添加到信任證書鏈中。而根證書我們自己給自己簽名的證書是給SSL協議用的。
KeyStore是用來保存key,證書的。
Tomcat的keystore有兩個
Server keystore: 存放的是服務器用的公私鑰key
Trust keystore:存放的是所有確定信任的證書。自己給自己頒發的證書當然是值得我們自己信任的。以后可以用來認證通信的另外一方,不過單向認證應該用不到,
publicstaticvoid main(String[] args) throws Exception {
//trustsotre, my root certificate
KeyStore store = KeyStore.getInstance("JKS");
// initialize
store.load(null, null);
KeyPair rootPair = generateKeyPair();
X500PrivateCredential rootCredential = createRootCredential(rootPair);
store.setCertificateEntry(TRUST_STORE_NAME, rootCredential.getCertificate());
store.store(
new FileOutputStream(TRUST_STORE_NAME + ".jks"),
TRUST_STORE_PASSWORD);
// server credentials
store = KeyStore.getInstance("JKS");
store.load(null, null);
store.setKeyEntry(
SERVER_NAME, rootCredential.getPrivateKey(), SERVER_PASSWORD,
new Certificate[] { rootCredential.getCertificate() });
store.store(
new FileOutputStream(SERVER_NAME + ".jks"), SERVER_PASSWORD);
}
|
將KeyStore文件配置在tomcat的server.xml中
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS"
keystoreFile="conf/server.jks" keystorePass="serverPassword" truststoreFile ="conf/trustStore.jks" truststorePass="trustPassword"/>
|
啟動tomcat即可
打開URL看看效果吧。

點是,就可以打開網頁了。