本件详细介绍了如何通过几个简单步骤在 Tomcat 中配置 SSL/TLS 、使用 JDK 生成自签名的证书,最终实现在应用中支持 HTTPS 协议。
生产密钥和证书
Tomcat 目前只能操作 JKS、PKCS11、PKCS12 格式的密钥存储库。JKS 是 Java 标准的“Java 密钥存储库”格式,是通过 keytool 命令行工具创建的。该工具包含在 JDK 中。PKCS12 格式一种互联网标准,可以通过 OpenSSL 和 Microsoft 的 Key-Manager 来。
创建一个 keystore 文件保存服务器的私有密钥和自签名证书:
Windows:
“%JAVA_HOME%\bin\keytool” -genkey -alias tomcat -keyalg RSA
UNIX:
$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA
执行该命令后,首先会提示你提供 keystore 的密码。Tomcat 默认使用的密码是 changeit
(全部字母都小写),当然你可以指定一个自定义密码(如果你愿意)。同样,你也需要将这个自定义密码在 server.xml
配置文件内进行指定,稍后再予以详述。
接下来会提示关于证书的一般信息,比如组织、联系人名称,等等。当用户试图在你的应用中访问一个安全页面时,该信息会显示给用户,所以一定要确保所提供的信息与用户所期望看到的内容保持一致。
最后,还需要输入密钥密码(key password),这个密码是这一证书(而不是存储在同一密码存储库文件中的其他证书)的专有密码。keytool 提示会告诉你,如果按下回车键,则自动使用密码存储库 keystore 的密码。当然,除了这个密码,你也可以自定义自己的密码。如果选择自定义密码,那么不要忘了在 server.xml
配置文件中指定这一密码。
该命令将在用户的主目录下创建一个新文件:.keystore
。
linux输入命令查找
# find / -name '*keystore'
找到的地址 /root/.keystore
要想指定一个不同的位置或文件名,可以在上述的 keytool 命令上添加 -keystore 参数,后跟到达 keystore 文件的完整路径名。你还需要把这个新位置指定到 server.xml
配置文件上,见后文介绍。例如:
Windows:
“%JAVA_HOME%\bin\keytool” -genkey -alias tomcat -keyalg RSA
-keystore \path\to\my\keystore
Unix:设置证书有效期为365天
$JAVA_HOME/bin/keytool -genkey -alias tomcat -keyalg RSA -validity 365 -keystore /path/to/my/keystore/.keystore
Tomcat 指定了 8443 端口为 HTTPS 访问端口。
修改配置
取消对 Tomcat 安装目录下 /conf/server.xml
中 “SSL HTTP/1.1 Connector” 一项的注释状态,并制定 keystore 的路径和密码:
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
keystoreFile="${user.home}/.keystore" keystorePass="changeit"
clientAuth="false" sslProtocol="TLS" />
Tomcat 指定了 8443 端口为 HTTPS 访问端口。
效果
首先,浏览器访问 HTTPS 支持的页面,https://192.168.1.143:8443
接着,浏览器访问 HTTP 的页面:
当用户首次访问你站点上的安全页面时,页面通常会提供给他一个对话框,包含证书相关细节(比如组织及联系方式等),并且询问他是否愿意承认该证书为有效证书,然后再进行下一步的事务。一些浏览器可能会提供一个选项,允许永远承认给出的证书的有效性,这样就不会在用户每次访问站点时打扰他们了。但有些浏览器不会提供这种选项。一旦用户承认了证书的有效性,那么在整个的浏览器会话期间,证书都被认为是有效的。
总结
虽然 SSL 协议的意图是尽可能有助于提供安全且高效的连接,但从性能角度来考虑,加密与解密是非茶馆耗费计算资源的,因此将整个 Web 应用都运行在 SSL 协议下是完全没有必要的,开发者需要挑选需要安全连接的页面。对于一个相当繁忙的网站来说,通常只会在特定页面上使用 SSL 协议,也就是可能交换敏感信息的页面,比如:登录页面、个人信息页面、购物车结账页面(可能会输入信用卡信息),等等。应用中的任何一个页面都可以通过加密套接字来请求访问,只需将页面地址的前缀 http:
换成 https:
即可。