IT技术博客大学习 共学习 共进步

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

UC技术博客 2013-09-15 22:37:57 浏览 981 次

前言

   据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 -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/

建议继续学习

  1. SSL证书的分类(按功能) (阅读 10,162)
  2. nginx 使用 ssl (阅读 7,564)
  3. 解决linux下安装ssl后,apache重启时需要密码 (阅读 6,384)
  4. SSL Proxy (阅读 5,043)
  5. 通过ssldump来分析ssl协议过程 (阅读 3,904)
  6. SSL窃听攻击实操 (阅读 3,764)
  7. 给Nginx配置一个自签名的SSL证书 (阅读 3,542)
  8. Linux下自行颁发SSL证书 (阅读 2,762)
  9. SSL多域名绑定证书的解决方案 (阅读 2,760)
  10. [Android]用WebView访问证书有问题的SSL网页 (阅读 2,745)