網(wǎng)上大多數(shù)文章都是用keytool生成自簽名根證書,將根證書配置在tomcat的server.xml中。我不太喜歡用keytool,原因:
1.我們可能換provider,不同的provider會(huì)有不同的算法實(shí)現(xiàn),算法的安全性和性能也可能不同,通過代碼生成比較方便一些,不同算法的實(shí)現(xiàn)要放在classpath上。
2.通過代碼生成還有一個(gè)好處,會(huì)對(duì)整個(gè)流程理解的比較清楚,實(shí)現(xiàn)的原理到底是怎樣的。
要用到https,也就是TLS或者SSL,我們需要有證書,要么是法定證書機(jī)構(gòu)(VeriSign,中國(guó)估計(jì)也有代理)給你簽發(fā)的可信證書,要么自己給自己頒發(fā)一個(gè)根證書。自己給自己頒發(fā)的證書,瀏覽器是不信任的,會(huì)彈出一個(gè)提示框。
SSL認(rèn)證分為雙向認(rèn)證和單向認(rèn)證(客戶端認(rèn)證服務(wù)器),一般做網(wǎng)站單向認(rèn)證就可,客戶端要認(rèn)證服務(wù)器端的證書,認(rèn)證通過,通過非對(duì)稱加密算法交換秘密密鑰,以后的通信數(shù)據(jù)通過秘密密鑰加密。
所以說要想用https,就得現(xiàn)有證書。有證書就得現(xiàn)有公私鑰。
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());
}
|
有了證書,我們要將證書存儲(chǔ)起來(lái),根證書是自簽名的證書,凡是通過根證書簽名頒發(fā)的證書都是可信任的。根證書需要添加到信任證書鏈中。而根證書我們自己給自己簽名的證書是給SSL協(xié)議用的。
KeyStore是用來(lái)保存key,證書的。
Tomcat的keystore有兩個(gè)
Server keystore: 存放的是服務(wù)器用的公私鑰key
Trust keystore:存放的是所有確定信任的證書。自己給自己頒發(fā)的證書當(dāng)然是值得我們自己信任的。以后可以用來(lái)認(rèn)證通信的另外一方,不過單向認(rèn)證應(yīng)該用不到,
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"/>
|
啟動(dòng)tomcat即可
打開URL看看效果吧。

點(diǎn)是,就可以打開網(wǎng)頁(yè)了。