网上大多数文章都是用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看看效果吧。

 
点是,就可以打开网页了。
