Tomcat配置SSL的关键步骤是把CA证书导入到keystore。然后配置JSSE或APR的Connector和Listener(APR模式)
Tomcat只支持JKS,PKCS11或PKCS12格式的keystore。JKS格式是Java标准,由keytool工具创建。PKCS12格式是Internet标准,可以通过OpenSSL和微软的Key-Manager创建。
可以把现有的keystore导入JKS,但是要注意的是OPENSSL支持key之前的注释,JKS不支持,导入前需删除。
以下命令行可以把CA证书导入到PKCS11 keystore:
openssl pkcs12 -export -in mycert.crt -inkey mykey.key \
-out mycert.p12 -name tomcat -CAfile myCA.crt \
-caname root -chain
使用如下命令创建子签名的JKSkeystore。文件名为.keystore
$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA
使用此命令后,会被要求输入密码,tomcat默认的密码是'changeit'。你可以指定自己的密码,但是如果这样的话,你需要在server.xml中配置新密码。
然后会被要求填写组织名称等信息。
最后会被要输入Key Password。Tomcat强制要求必须和之前输入的keystore password相同。(如果不相同,启动tomcat时会看到java.io.IOException: Cannot recover key的异常)
证书生成完毕。
开始配置server.xml
Tomcat支持两种SSL的实现方式:
- JSSE实现,JDK内置
- APR实现
- 启用APR时,HTTPS connector将使用socket poller实现keepalive,使用OpenSSL实现
可以选择不配置实现方式,Tomcat会自动选择,如果安装了Tomcat native library,则选用APR方式,否则使用JSSE方式。
以下是手动配置:
- JSSE方式 blocking或non-blocking
<– Define a blocking Java SSL Coyote HTTP/1.1 Connector on port 8443 –> <Connector protocol=”org.apache.coyote.http11.Http11Protocol” port=”8443″ …/> <– Define a non-blocking Java SSL Coyote HTTP/1.1 Connector on port 8443 –> <Connector protocol=”org.apache.coyote.http11.Http11NioProtocol” port=”8443″ …/>
- APR方式(Apache Portable Runtime,可提高性能)
<– Define a APR SSL Coyote HTTP/1.1 Connector on port 8443 –> <Connector protocol=”org.apache.coyote.http11.Http11AprProtocol” port=”8443″ …/>
如果APR方式,又安装了native lib可以用如下的built in引擎
<Listener className=”org.apache.catalina.core.AprLifecycleListener” SSLEngine=”on” SSLRandomSeed=”builtin” /> 如果没有安装native lib支持,就将其设置为off(需OpenSSL)
<Listener className=”org.apache.catalina.core.AprLifecycleListener” SSLEngine=”off” />
SSLRandomSeed表示随机种子,生产环境中需要一个可靠的源,非阻塞的/dev/urandom是个不错的选择。
最后是配置Connector
- JSSE方式 * 注意,如果安装了Native lib配置JSSE会报错。删除${tomcat}/bin/tcnative-1.dll或者手动指定protocol=”org.apache.coyote.http11.Http11NioProtocol”即可
<– Define a SSL Coyote HTTP/1.1 Connector on port 8443 –> <Connector port=”8443″ maxThreads=”200″ scheme=”https” secure=”true” SSLEnabled=”true” keystoreFile=”${user.home}/.keystore” keyAlias=”tomcat”
keystorePass=”changeit” clientAuth=”false” sslProtocol=”TLS”/>
其中clientAuth用于指定是否需要客户端提供证书
<– Define a SSL Coyote HTTP/1.1 Connector on port 8443 –> <Connector port=”8443″ maxThreads=”200″ scheme=”https” secure=”true” SSLEnabled=”true” SSLCertificateFile=”/usr/local/ssl/server.crt” SSLCertificateKeyFile=”/usr/local/ssl/server.pem” clientAuth=”optional” SSLProtocol=”TLSv1″/> 经过以上的配置,Tomcat已经可以使用https了。不过浏览器会有https证书警告,因为证书是自己签的,不是CA。下面介绍如何配置CA证书。
- 首先创建CSR
- 创建本地证书
- keytool -genkey -alias tomcat -keyalg RSA -keystore <your_keystore_filename>
- 在输入first and lastname时候输入域名,例如www.abc.com
- 然后创建CSR
- keytool -certreq -keyalg RSA -alias tomcat -file certreq.csr -keystore <your_keystore_filename>
- 获得了certreq.csr这就是一个CSR文件,把CSR提交给CA,CA会发送给你证书
- 导入证书
- 导入之前必须要在keystore中导入证书链或根证书。找CA厂商咨询。
- keytool -import -alias root -keystore <keystore_filename> -trustcacerts -file <filename_of_the_chain_certificate>
- 正式导入证书
- keytool -import -alias tomcat -keystore <keystore_filename> -file <certificate_filename>
对于Java客户端来说,例如用httpclient需要用https访问web site,也需要导入服务器端证书。方法如下(Kenny提供):
java里取得一台https server的证书并import到本地信任列表的方法是: 下载InstallCert.class ,放到/tmp ,执行javac InstallCert.class 编译成InstallCert.java 执行java InstallCert 192.168.0.201:636 (参数是ldaps server名字和端口) 根据提示,选择将证书加入信任的keystore,会生成jssecacerts文件 . 将jssecacerts拷贝至<JAVA_HOME>\jre\lib\security 在app应用的server上,就做了下java InstallCert 10.208.101:109:8443 生成jssecacerts就可以了。 关键还是访问app通过https访问server时要用域名,并且这个域名要与生成证书时的域名一样