苹果AppStore要求:2017年1月1日起,所有上线苹果App Store的应用都必须启用 App Transport Security(ATS)安全功能。AppTransportSecurity(ATS)是苹果在iOS9中引入的一项隐私保护功能,屏蔽明文HTTP资源加载,连接必须经过更安全的HTTPS协议。据此我们有理由相信:掌握点安全方面的编程还是有必要的!
特别说明:本文档主要是为了做一个关于Netty、SSL/TLS方面的概括性介绍,着重于具体编码实现,文中部分图片、文字内容来自网络(如有侵权请告知本人删除),在此也对原文作者表示感谢!
采用Netty框架,实现SSL/TLS支持,完成Socket服务端和客户端,以及Http服务端和客户端的程序开发。(代码下载)
Java的Socket通信模式经过:BIO(同步阻塞)-> NIO(非阻塞)->AIO(异步非阻塞)
Netty是一款异步的事件驱动的网络应用框架和工具,用于快速开发可维护的高性能、高扩展性协议服务器和客户端。
1、JDK自带的NIO类库和API繁杂,使用麻烦,不易开发高质量可靠性程序;而Netty提供的API使用简单。
2、Netty的功能强大,预置多种编解码,支持多种协议。
3、定制能力强,可通过ChannelHandler对通信框架灵活扩展。
4、性能高,同其它NIO框架对比,Netty的综合性能最优。
5、成熟、稳定,已有大规模不同行业的商业应用。
6、社区活跃。
1、实现Socket通信服务端和客户端,具体见代码。
2、主要类: Channel、ChannelHandler、ChannelPipeline、ChannelHandlerContext;
其中ChannelHandler又分为ChannelInboundHandler、ChannelOutboundHandler两大类。
它们关系图:
(图1)
(图2)
(图3)
1、网络分层模型:
(图4)
(图5)
2、网络包分析工具:Wireshark
(图6)
我们主要关注第四层:传输层。
3、TCP三次握手
(图7)
SSL是安全套接层(Secure Socket Layer)的缩写;
TLS表示传输层安全(Transport LayerSecurity)的缩写。
SSL最初由网景公司提出,最初目的是为了保护web安全,现在用来提高传输层的安全。
TLS是IETF基于SSLv3制定的标准,两者基本一致,只有少许的差别。
使用SSL/TLS的通信,就是为了防止信息被第三方窃听、篡改、冒充。
SSLv3/TLS处于传输层和应用层之间,分为握手层和记录层,如下图所示:
(图8)
握手过程:
(图9)
注:Finished亦是Encrypted Handshake Message
这个过程可以通过一个相亲过程来“解释”一下:(做了点添油加醋的步骤:Application Data、Encrypted Alert,但也属协议的一部分)
(图10)
说明:Server Key Exchange 跟所选加密算法有关,如果是RSA算法则不需要此步骤,若是DSA算法则需要。certificaterequest、certificate和certificate_verify在双向认证时才有,其中certificate_verify是客户端用自己的私钥签名前面握手消息的结果,给服务端认证客户端的证书certificate是否合法。
5.1使用keytool自签名制作证书:
keytool是JDK自带工具。
5.1.1 单向认证
1) 生成Netty服务端私钥和证书仓库命令:
keytool -genkey-alias sserver -keysize 2048 -validity 365 -keyalg RSA -dname "CN=server,OU=HR, O=ESHORE, L=GZ, ST=GD, C=CN" -keypass servers -storepass servers-keystore server_s.jks
2) 生成Netty服务端自签名证书:
keytool -export-alias sserver -keystore server_s.jks -storepass servers -file server_s.cer
3) 生成客户端的密钥对和证书仓库,命令如下:
keytool -genkey-alias sclient -keysize 2048 -validity 365 -keyalg RSA -dname "CN=client,OU=HR2, O=ESHORE, L=GZ, ST=GD, C=CN" -keypass clients -storepass clients-keystore client_s.jks
4) 将Netty服务端的证书导入到客户端的证书仓库中,命令如下:
keytool -import-trustcacerts -alias sserver -file server_s.cer -storepass clients -keystore client_s.jks
5.1.2 双向认证(接上面的单向认证)
1) 生成客户端的自签名证书:
keytool -export -alias sclient -keystore client_s.jks -storepass clients -file client_s.cer
2) 将客户端的自签名证书导入到服务端的信任证书仓库中:
keytool -import -trustcacerts -alias sclient -file client_s.cer -storepass servers -keystore server_s.jks
5.2 基于第三方CA认证
需要安装工具:OpenSSL
先准备必要的目录和文件:
mkdir -p ./demoCA/{private,newcerts}
touchdemoCA/index.txt
echo 01 >demoCA/serial
5.1 服务端证书制作:
这里根据两种算法:RSA和DSA 分别建立证书;如果不指明DSA,则属于RSA建立步骤。
步骤1:利用OpenSSL生成CA证书:
openssl req -new -x509 -keyout ca.key -out ca.crt -days 365
或分步:
openssl genrsa-des3 -out ./demoCA/private/cakey.pem 2048
openssl req -new -days 365 -key ./demoCA/private/cakey.pem -out careq.pem
openssl ca -selfsign -in careq.pem -out ./demoCA/cacert.pem
采用DRA算法建立:
/*生成1024位的密钥参数*/
openssl dsaparam-out DSAP.pem 1024
/*生成密钥并使用des3加密存储*/
openssl gendsa -out./demoCA/private/cakey_DSA.pem -des3 -passout pass:cakey DSAP.pem
openssl req -new -days 365 -key ./demoCA/private/cakey_DSA.pem -out careq_DSA.pem
/*执行下面命令前,需要把./demoCA/private/cakey_DSA.pem文件名改为cakey.pem */
openssl ca-selfsign -in careq_DSA.pem -out ./demoCA/cacert_DSA.pem
步骤2:生成Netty服务端私钥和证书仓库命令:
keytool -genkey -alias sserver -keysize 2048 -validity 365 -keyalg RSA -dname "CN=server,OU=HR, O=ESHORE, L=GZ, ST=GD, C=CN" -keypass serverkey -storepass servers -keystore server.jks
注意:上面命令中,由于-keypass和-storepass 密码设置不一样,导致服务端在接收到客户端连接请求时,报错:java.security.UnrecoverableKeyException: Cannot recover key
可以通过下面命令,把两个密码改为一样(都为servers),即可解决:
keytool -keypasswd -new servers -keystore server.jks -storepass servers -alias sserver -keypass serverkey
采用DRA算法建立:
keytool -genkey -alias sserver -keysize 1024 -validity 365 -keyalg DSA -dname "CN=server_DSA, OU=HR, O=ESHORE, L=GZ, ST=GD, C=CN" -keypass servers -storepass servers -keystore server_DSA.jks
步骤3:生成证书签名请求:
keytool -certreq-alias sserver -sigalg MD5withRSA -file server.csr -keypass serverkey -storepass servers -keystore server.jks
采用DRA算法建立:
keytool -certreq -alias sserver -sigalg SHA1withDSA -file server_DSA.csr -keypass servers -storepass servers -keystore server_DSA.jks
步骤4:用CA私钥进行签名:
openssl ca -inserver.csr -out server.crt
采用DRA算法建立:
openssl ca -inserver_DSA.csr -out server_DSA.crt -cert ./demoCA/cacert_DSA.pem -keyfile ./demoCA/private/cakey_DSA.pem
步骤5:导入信任的CA根证书到keystore
keytool -import -v -trustcacerts -alias ca_root -file ./demoCA/cacert.pem -storepass servers -keystore server.jks
采用DRA算法建立:
keytool -import -v -trustcacerts -alias ca_root -file ./demoCA/cacert_DSA.pem -storepass servers -keystore server_DSA.jks
步骤6:将CA签名后的server端证书导入keystore
keytool -import -v -alias sserver -file server.crt -keypass servers -storepass servers -keystore server.jks
采用DRA算法建立:
keytool -import -v -alias sserver -file server_DSA.crt -keypass servers -storepass servers -keystore server_DSA.jks
5.2 客户端证书制作:
步骤1:生成客户端密钥对:
keytool -genkey -alias sclient -keysize 2048 -validity 365 -keyalg RSA -dname "CN=client,OU=HR2, O=ESHORE, L=GZ, ST=GD, C=CN" -keypass clients -storepass clients-keystore client.jks
采用DRA算法建立:
keytool -genkey -alias sclient -keysize 1024 -validity 365 -keyalg DSA -dname"CN=client_DSA, OU=HR2, O=ESHORE, L=GZ, ST=GD, C=CN" -keypass clients -storepass clients -keystore client_DSA.jks
步骤2:生成证书签名请求:
keytool -certreq -alias sclient -sigalg MD5withRSA -file client.csr -keypass clients -storepass clients -keystore client.jks
采用DRA算法建立:
keytool -certreq -alias sclient -sigalg SHA1withDSA -file client_DSA.csr -keypass clients -storepass clients -keystore client_DSA.jks
步骤3:用CA私钥进行签名:
openssl ca -in client.csr -out client.crt
采用DRA算法建立:
openssl ca -in client_DSA.csr -out client_DSA.crt -cert ./demoCA/cacert_DSA.pem -keyfile ./demoCA/private/cakey_DSA.pem
步骤4:导入信任的CA根证书到keystore:
keytool -import -v -trustcacerts -alias ca_root -file ./demoCA/cacert.pem -storepass clients -keystore client.jks
采用DRA算法建立:
keytool -import -v -trustcacerts -alias ca_root -file ./demoCA/cacert_DSA.pem -storepass clients -keystore client_DSA.jks
步骤5:将CA签名后的client端证书导入keystore:
keytool -import -v -alias sclient -file client.crt -keypass clients -storepass clients -keystore client.jks
采用DRA算法建立:
keytool -import -v -alias sclient -file client_DSA.crt -keypass clients -storepass clients -keystore client_DSA.jks
1、Netty系列之Netty安全性:
http://www.infoq.com/cn/articles/netty-security
2、Netty 各个类的讲解:
http://blog.csdn.net/z69183787/article/details/52623501
3、用Wireshark 图解 TCP 三次握手:
http://blog.jobbole.com/108194/?utm_source=blog.jobbole.com&utm_medium=relatedPosts
4、SSL协议详解:
http://kb.cnblogs.com/page/162080/
5、使用wireshark观察SSL/TLS握手过程--双向认证/单向认证:
http://blog.csdn.net/fw0124/article/details/40983787
6、HTTPS到底是个啥玩意儿:
http://blog.csdn.net/zgwangbo/article/details/50889623
7、图解SSL/TLS协议:
http://blog.csdn.net/fw0124/article/details/40875629
8、Handler的执行顺序:
https://my.oschina.net/jamaly/blog/272385
9、基于OpenSSL 的 CA 建立及证书签发:
http://rhythm-zju.blog.163.com/blog/static/310042008015115718637/
10、OpenSSL 非对称加密算法DSA命令详解:
http://www.linuxidc.com/Linux/2016-04/130493.htm
--------------------- 本文来自 wujyou 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/wujyou/article/details/53816722?utm_source=copy