基于Nginx的http_sssl_cert双向认证配置
背景
HTTPS是工作于SSL层之上的HTTP协议,SSL(安全套接层)工作于TCP层之上,向应用层提供了两个基本安全服务:认证和保密。SSL有三个子协议:握手协议,记录协议和警报协议。其中握手协议实现服务器与客户端的认证与密钥交换,记录协议进行数据加密并保证数据的完整性,警报协议则规定了错误类型和处理机制。
流程
认证流程
单向认证
-
客户端发起建立HTTPS连接请求,将SSL协议版本的信息发送给服务器端;
-
服务器端将本机的公钥证书(server.crt)发送给客户端;
-
客户端读取公钥证书(server.crt),取出了服务端公钥;
-
客户端生成一个随机数(密钥R),用刚才得到的服务器公钥去加密这个随机数形成密文,发送给服务端;
-
服务端用自己的私钥(server.key)去解密这个密文,得到了密钥R
-
服务端和客户端在后续通讯过程中就使用这个密钥R进行通信了。
如图为单向认证流程
双向认证
- 客户端发起建立HTTPS连接请求,将SSL协议版本的信息发送给服务端;
- 服务器端将本机的公钥证书(server.crt)发送给客户端;
- 客户端读取公钥证书(server.crt),取出了服务端公钥;
- 客户端将客户端公钥证书(client.crt)发送给服务器端;
- 服务器端使用根证书(root.crt)解密客户端公钥证书,拿到客户端公钥;
- 客户端发送自己支持的加密方案给服务器端;
- 服务器端根据自己和客户端的能力,选择一个双方都能接受的加密方案,使用客户端的公钥加密8. 后发送给客户端;
- 客户端使用自己的私钥解密加密方案,生成一个随机数R,使用服务器公钥加密后传给服务器端;
- 服务端用自己的私钥去解密这个密文,得到了密钥R
- 服务端和客户端在后续通讯过程中就使用这个密钥R进行通信了。
如图为双向认证流程
生成
自签名证书生成
- 1.ca证书生成(ca私钥)
1 | mkdir /etc/nginx/keys/ |
- 2.ca数字证书生成
1 | openssl req -new -x509 -days 3650 -key ca.key -out ca.crt |
信息Common name 填写域名或ip地址,其余随意填写
-
- 用 CA 私钥签发 server 的数字证书
1 | openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650 |
-
- 生成客户端的私钥与证书
1 | openssl genrsa -out client.key 4096 |
-
- 生成客户端数字证书
1 | openssl req -new -key client.key -out client.csr |
信息与ca保持一致
-
- openssl req -new -key client.key -out client.csr
1 | openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 3650 |
Nginx配置
安装nginx并启用ssl模块
- nginx配置文件如下:
1 | server { |
在测试前重新nginx
1 | nginx -t |
测试
java测试
- 代码如下
1 | import org.apache.http.HttpEntity; |
- 测试方法如下
1 | cd $JAVA_HOME |
curl 工具测试
- demo
1 | curl -v |
- test
1 | curl --cacert ca.crt --cert client.crt --key client.key --tlsv1.2 https://192.168.0.162 |
- detail
1 | #--cert指定客户端公钥证书的路径 |
- test demo
如图
- succ demo
如图