Tomcat HTTPS 证书制作
1.创建keystore
cd E:\Server\keystore
keytool -genkeypair -keyalg RSA -keysize 2048 -sigalg SHA1withRSA -validity 36500 -alias tomcat -keystore laimuduo.keystore -dname "CN=passport.laimuduo.com,OU=laimuduo,O=laimuduo,L=shanghai,ST=shanghai,C=CN"
秘钥库口令和秘钥口令均设为111111
2.导出数字证书
keytool -exportcert -alias tomcat -keystore laimuduo.keystore -file laimuduo.cer -rfc
3.导入到客户端Java证书库
cd %JAVA_HOME%\jre\lib\security
keytool -import -alias laimuduo -keystore laimuduo -file E:\Server\keystore\laimuduo.cer -trustcacerts
4.tomcat server.xml配置
复制 laimuduo.keystore 到 %CATALINA_HOME% 目录下与config目录同级或者直接指定绝对路径
<!-- Define a SSL Coyote HTTP/1.1 Connector on port 8443 -->
<Connector
protocol="org.apache.coyote.http11.Http11NioProtocol"
port="8443" maxThreads="200"
scheme="https" secure="true" SSLEnabled="true"
keystoreFile="laimuduo.keystore" keystorePass="111111"
clientAuth="false" sslProtocol="TLS"/>
5.keytool 常用命令
列出密钥库中的条目(默认文件位置:C:\Users\Administrator.keystore)
keytool -list -keystore laimuduo.keystore
删除条目
keytool -delete -keystore laimuduo.keystore -alias laimuduo
打印证书内容
keytool -printcert -file "laimuduo.cer"
6.Windows vs Ubuntu
实际操作中发现 windows 下生成keystore时需要指定 -alias tomcat 否则启动tomcat会报
01-Nov-2016 20:39:37.990 WARNING [main] org.apache.tomcat.util.net.openssl.OpenSSLContext.init Error initializing SSL context
java.lang.NullPointerException
at org.apache.tomcat.util.net.openssl.OpenSSLContext.init(OpenSSLContext.java:281)
at org.apache.tomcat.util.net.AbstractJsseEndpoint.createSSLContext(AbstractJsseEndpoint.java:101)
at org.apache.tomcat.util.net.AbstractJsseEndpoint.initialiseSsl(AbstractJsseEndpoint.java:81)
at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:244)
at org.apache.tomcat.util.net.AbstractEndpoint.init(AbstractEndpoint.java:866)
at org.apache.tomcat.util.net.AbstractJsseEndpoint.init(AbstractJsseEndpoint.java:213)
at org.apache.coyote.AbstractProtocol.init(AbstractProtocol.java:575)
at org.apache.coyote.http11.AbstractHttp11Protocol.init(AbstractHttp11Protocol.java:65)
at org.apache.catalina.connector.Connector.initInternal(Connector.java:944)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107)
at org.apache.catalina.core.StandardService.initInternal(StandardService.java:549)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107)
at org.apache.catalina.core.StandardServer.initInternal(StandardServer.java:873)
at org.apache.catalina.util.LifecycleBase.init(LifecycleBase.java:107)
at org.apache.catalina.startup.Catalina.load(Catalina.java:606)
at org.apache.catalina.startup.Catalina.load(Catalina.java:629)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:311)
at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:494)
查看
org.apache.tomcat.util.net.openssl.OpenSSLContext
源代码 位于 %CATALINA_HOME%\lib\tomcat-coyote.jar 发现当certificate.getCertificateKeyAlias() == null
时会取默认秘钥为tomcat
的条目
{
X509KeyManager keyManager = chooseKeyManager(kms);
String alias = this.certificate.getCertificateKeyAlias();
if (alias == null) {
alias = "tomcat";
}
X509Certificate[] chain = keyManager.getCertificateChain(alias);
PrivateKey key = keyManager.getPrivateKey(alias);
StringBuilder sb = new StringBuilder("-----BEGIN RSA PRIVATE KEY-----\n");
String encoded = BASE64_ENCODER.encodeToString(key.getEncoded());
if (encoded.endsWith("\n")) {
encoded = encoded.substring(0, encoded.length() - 1);
}
sb.append(encoded);
sb.append(END_KEY);
org.apache.tomcat.jni.SSLContext.setCertificateRaw(this.ctx, chain[0].getEncoded(), sb.toString().getBytes(StandardCharsets.US_ASCII), 0);
for (int i = 1; i < chain.length; i++) {
org.apache.tomcat.jni.SSLContext.addChainCertificateRaw(this.ctx, chain[i].getEncoded());
}
}