1. 概述
通常,在安全网络通信中会启用SSL(Secure Socket Layer)来保护交互数据的安全性,由于SSL是认证型协议(通信双方或一方需要出示安全认证证书才可以建立连接),所以会涉及到数字证书及证书认证的内容。
对于Tomcat服务器来说,通过HTTPS(Secure Hypertext Transfer Protocol)安全超文本传输协议来构建安全的HTTP通信。而HTTPS的安全基础是SSL。
关于Tomcat的SSL配置的文章网上已有很多,但是大多不是很清晰,有些只是给出了示例,而没有中肯的建议,尤其是对Tomcat 6.x下的SSL配置。本文在参考大量资料和实践的基础上深入探索Tomcat 6.x下的SSL配置,其中包括JSSE和OpenSSL的单向和双向认证配置。希望对读者有所帮助!也欢迎朋友批评指正!
2. 环境准备
l apache-tomcat-6.0.26
下载apache-tomcat-6.0.26-windows-x86.zip版本,该版本带有windows下APR的DLL(tcnative-1.dll)。安装到本地,如:D:\Server\apache-tomcat-6.0.26。本文中使用$Tomcat_Home指代Tomcat安装目录,此处指向D:\Server\apache-tomcat-6.0.26。
l OpenSSL
下载Win32 OpenSSL v1.0.0a Light,该工具用于生成证书。安装到本地,如D:\Server\OpenSSL-Win32。本文中使用$OpenSSL_Home指代OpenSSL的安装目录,指向D:\Server\OpenSSL-Win32。
l Tomcat6.x Connector架构的了解
比较$Tomcat_Home\conf\server.xml中的配置片段
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
keystoreFile="keystore/tomcat.jks" keystorePass="123456"
clientAuth="false" sslProtocol="TLS" />
和
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
keystoreFile="keystore/tomcat.jks" keystorePass="123456"
clientAuth="false" sslProtocol="TLS" />
如果你没有明白这两段的区别,那么请先阅读《Tomcat6.0 源码学习--Connector架构》一文。
3. Tomcat6.x的APR
由《Tomcat6.0 源码学习--Connector架构》一文可知,Tomcat6.x可以使用APR来提升服务器对静态资源的处理能力。默认情况下$Tomcat_Home\conf\server.xml中启用了APR,如下片段指定:
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
但是要想获得APR的支持,还需要有相关平台下的本地APR库,关于如何获得本地库请参考Tomcat的文档。
这里只给出检查当前Tomcat服务器是否支持APR的方法。查看服务日志文件$Tomcat_Home\logs\catalina.2010-06-22.log:
2010-6-22 10:04:35 org.apache.catalina.core.AprLifecycleListener init
信息: Loaded APR based Apache Tomcat Native library 1.1.20.
2010-6-22 10:04:35 org.apache.catalina.core.AprLifecycleListener init
信息: APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true].
2010-6-22 10:04:35 org.apache.coyote.http11.Http11AprProtocol init
信息: Initializing Coyote HTTP/1.1 on http-8080
2010-6-22 10:04:35 org.apache.coyote.http11.Http11AprProtocol init
信息: Initializing Coyote HTTP/1.1 on http-8443
2010-6-22 10:04:35 org.apache.coyote.ajp.AjpAprProtocol init
信息: Initializing Coyote AJP/1.3 on ajp-8009
如果看到上面红色信息则表示Tomcat服务器支持APR。如果日志信息为:
2010-6-21 14:27:18 org.apache.catalina.core.AprLifecycleListener init
2010-6-21 14:27:18 org.apache.coyote.http11.Http11Protocol init
信息: Initializing Coyote HTTP/1.1 on http-8080
2010-6-21 14:27:19 org.apache.coyote.http11.Http11Protocol init
信息: Initializing Coyote HTTP/1.1 on http-8443
则表示Tomcat服务器虽然启用了APR,但不支持APR。
这里介绍APR的原因是,Connector的配置与是否支持APR有着微妙的关系,如下的Connector配置在支持APR的情况下就会出错哦!
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
keystoreFile="keystore/tomcat.jks" keystorePass="123456"
clientAuth="false" sslProtocol="TLS" />
因为此配置使Connector实例加载org.apache.coyote.http11.Http11AprProtocol协议处理器,而Http11AprProtocol没有keystoreFile属性,所以在启动时会报错!
因此,这里推荐的Connector配置方式为:
<Connector port="8443"
protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
keystoreFile="keystore/tomcat.jks" keystorePass="123456"
clientAuth="false" sslProtocol="TLS" />
或
<Connector port="8443"
protocol=" org.apache.coyote.http11.Http11AprProtocol"
maxHttpHeaderSize="8192"
maxThreads="150"
enableLookups="false" disableUploadTimeout="true"
acceptCount="100" scheme="https" secure="true"
SSLEnabled="true"
SSLCertificateFile="${catalina.base}/ keystore/servercert.pem"
SSLCertificateKeyFile="${catalina.base}/ keystore/serverkey.pem" />
4. JSSE服务器端SSL认证
JSSE(Java Security Socket Extension,Java安全套接字扩展)是Sun为了解决在Internet上的安全通讯而推出的解决方案。它实现了SSL和TSL(传输层安全) 协议。在JSSE中包含了数据加密,服务器验证,消息完整性和客户端验证等技术。通过使用JSSE,客户机和服务器之间通过TCP/IP协议安全地传输数据。
下面介绍基于JSSE的Server端SSL认证配置。
4.1自签名证书配置
Step1,配置Connector,修改文件$Tomcat_Home\conf\server.xml添加如下片段
<Connector port="8443"
protocol="org.apache.coyote.http11.Http11NioProtocol"
SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
keystoreFile="keystore/tomcat.jks"
keystorePass="123456"
clientAuth="false"
sslProtocol="TLS" />
这里配置一个非阻塞的java SSL的http1.1的连接器,监听8443端口。
keystoreFile指定了密钥库文件的位置,该值可以为相对于$Tomcat_Home的位置。
keystorePass指定了密钥库的密码,默认为changeit。
clientAuth指定是否启用客户端验证,默认为false,不启用客户端验证。
Step2,创建服务器端的签名证书
我们知道,为了保证证书的真实性,需要给证书签名。通常这是由第三方的CA(Certification Authentication )来签发。在这里我们使用自签名的证书。
在命令行下使用如下命令:
keytool -genkey -alias serverkey -keyalg RSA -keypass 123456 -dname "CN=192.168.8.221 OU=bluesky o=software L=beijing ST=beijing C=CN" -keystore tomcat.jks -storepass 123456
说明:
1. 此命令在当前目录下生成一个密钥库文件tomcat.jks,该密钥库的密码为123456。
2. 此命令还产生一个密钥对(其私钥别名为serverkey)和一个包含公钥信息的证书,其私钥为123456,证书的主题信息为“CN=192.168.8.221 OU=bluesky o=software L=beijing ST=beijing C=CN”,同时,该证书由私钥签名。
3. 证书跟私钥绑定形成一条密钥实体存储在tomcat.jks中,可以通过别名serverkey来访问证书。
4. 命令具体的各项意义请参加相关文档。
注意:
这里要求keystore 和certificate的密码一致,此为Tomcat的约束。
Step3,在$Tomcat_Home目录下新建目录keystore,并拷贝tomcat.jks到其目录下。
Step4,测试Https,启动Tomcat。
访问https://localhost:8443/,提示有不安全的证书如下:
Tomcat6.X SSL的配置-Part1 - dinstone - dinstone的代码人生!
安全警报
Tomcat6.X SSL的配置-Part1 - dinstone - dinstone的代码人生!
证书信息
该警报说明存在2个疑点不能将https://localhost:8443/视为安全站点:
1. 该安全证书不是由可信任的机构颁发。因为不能验证签发该证书的机构的真实性,从而导致了该证书的不可信。下面我们通过自制的CA证书来签发该证书来解决这个问题(一般是通过第三方CA来签发)。
2. 安全证书上的名称与访问的站点名称不一致。证书上的名称为192.168.8.221,而站点名称为localhost。
而访问https://192.168.8.221:8443/,则会提示有不安全的证书如下:
Tomcat6.X SSL的配置-Part1 - dinstone - dinstone的代码人生!
由于证书的名称跟站点名称一致,所以疑点减少为1个了。
源地址
http://blog.163.com/haizai219@126/blog/static/44412555201052332951865/