β

以keystore方式为play!应用建立单向/双向SSL

UC技术博客 261 阅读
ssl

前言

play!官网介绍,play!内置容器支持HTTPS协议,有两种实现方式,一种是X.509方式,另一种是keystore方式。不过官网上对整个流程的配置并不完整,下文主要介绍后一种方式的配置全过程,以免各位被网上过时文章误导。

为了便于读者理解配置过程,有必要提及一下SSL的原理。简单说来,就是对称加密算法+非对称加密算法。其中,前者用于加密、解密双方要传输的明文;而一个对称加密的明文是否容易被窃取,主要取决于加密的密钥是否安全,于是,提供会话级别的加密密钥成为后者的重要任务。一般,SSL的非对称加密使用RSA算法,公钥在对外公开的证书中,用于给对方加密那个会话级别的对称加密密钥,私钥自己保存,用于解密,从而获得对方将要使用的对称加密密钥。

对于单向SSL,这么解释就差不多了。双向SSL,解决的是服务端只向特定用户提供服务的问题,例如网银的U盾,再例如我们在做的公司内重要的基础服务。做法是在服务端提前对其信任的客户端进行授信,也就是导入客户端的证书。服务端收到请求时,要求客户端出示其证书,服务端把它与经过授信的证书进行比较,相符才允许访问,不相符就断开连接。因为客户端证书还需要密钥口令才能打开,而且还带有当前机器、用户信息,所以一般情况下,不存在被冒认的可能。


play!配置

添加SSL端口

application.conf文件中,在http.port一行下面添加https端口:

https.port=9443

指定keystore密钥库

同样在application.conf文件中,指定keystore密钥库及其算法、密钥库口令等。如果需要双向认证,clientAuth一行填need,否则填none或者把该行删除:

keystore.algorithm=JKS
keystore.password=123456
keystore.file=conf/certificate.jks
play.netty.clientAuth=need

生成服务端证书和密钥库

本节在服务端主机上进行操作。

在play!的conf目录下,使用keytool命令为ucmha项目生成密钥库(即keystore文件,名字与play!中的配置相同)和服务器的密钥对(证书/公钥+私钥)。

keytool -genkeypair -alias ucmha -keyalg RSA -keystore certificate.jks

以下选项根据应用需要而定:

您的名字与姓氏是什么?
[Unknown]: ucmha
您的组织单位名称是什么?
[Unknown]: platform
您的组织名称是什么?
[Unknown]: ucweb
您所在的城市或区域名称是什么?
[Unknown]: guangzhou
您所在的省/市/自治区名称是什么?
[Unknown]: guangdong
该单位的双字母国家/地区代码是什么?
[Unknown]: cn

注意,上述过程中,对于密钥库密钥都要求输入初始化口令,经验证,两者必须相同,才能正常使用。

如果只要单向SSL,配置过程到此结束

重启play!后,用curl命令试验,一般我们对自签名的证书不进行验证,所以用了-k/–insecure参数:

curl --insecure --sslv3 --location https://127.0.0.1:9443/

生成客户端证书和密钥库

本节在客户端主机上进行操作。

生成PKCS12密钥库

在任意目录下,使用keytool命令为myclient生成PKCS12密钥库。

keytool -genkey -alias myclient -keyalg RSA -storetype PKCS12 -keystore myclient.p12

导出客户端证书

在密钥库myclient.p12中导出客户端的证书myclient.cer,准备传给服务端进行授信。

keytool -export -alias myclient -keystore myclient.p12 -storetype PKCS12 -file myclient.cer

客户端导入自己的证书

如果是curl命令,不需要导入也没有地方保存,要在请求时自带证书,详见后面的执行命令。

如果是浏览器,以chrome浏览器为例,地址栏输入:

chrome://settings/certificates

在“您的证书”标签选择“导入…”,选择myclient.p12证书文件,输入其密码,选择“完成”。


服务端信任客户端证书

本节在服务端主机上进行操作。

服务端对客户端证书授信

在play!的conf目录下,使用keytool命令导入客户端的证书myclient.cer到服务端的密钥库certificate.jks。

keytool -import -alias myclient -file myclient.cer -keystore certificate.jks

检查是否已授信

keytool -list -keystore certificate.jks

最后,重启play服务即可。

如果使用curl命令验证,因为curl只支持DER、PEM或者ENG格式的证书,所以还要转换一下,111111为转换后的证书口令:

openssl pkcs12 -in myclient.p12 -out myclient.pem -clcerts
curl --insecure --sslv3 --location --cert myclient.pem:111111 https://127.0.0.1:9443/

如果使用浏览器验证,按页面要求出示已导入的客户端证书即可。


参考资料

http://www.vamsi-pavan.com/blog/http-ssl-curl-part3/

ssl
作者:UC技术博客
tech.uc.cn
原文地址:以keystore方式为play!应用建立单向/双向SSL, 感谢原作者分享。