網上大多數文章都是用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() - 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看看效果吧。
點是,就可以打開網頁了。