https双向认证

[复制链接]
发表于 2025-11-27 16:44:06 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
一、https双向认证原理

   
   双向认证流程
  

  • 客户端发起创建HTTPS毗连哀求,将SSL协议版本的信息发送给服务端;
  • 服务器端将本机的公钥证书(server.crt)发送给客户端;
  • 客户端读取公钥证书(server.crt),取出了服务端公钥;
  • 客户端将客户端公钥证书(client.crt)发送给服务器端;
  • 服务器端利用根证书(root.crt)解密客户端公钥证书,拿到客户端公钥;
  • 客户端发送自己支持的加密方案给服务器端;
  • 服务器端根据自己和客户端的本领,选择一个双方都能担当的加密方案;
  • 利用客户端的公钥加密. 后发送给客户端;
  • 客户端利用自己的私钥解密加密方案,天生一个随机数R,利用服务器公钥加密后传给服务器端;
  • 服务端用自己的私钥去解密这个密文,得到了密钥R;
  • 服务端和客户端在后续通讯过程中就利用这个密钥R举行通讯了。
  双向认证的目的告急是使得双方终极可以安全的得到秘钥R,反面全部传输都是通过秘钥R加密HTTPS双向认证,不但仅必要用户欣赏器校验服务器数字证书,还必要服务器端验证用户是否是可信的。
  二、证书天生

  如果要把整个双向认证的流程跑通,终极必要8个证书文件:
  

  • 根证书:root.crt;
  

  • 服务器端公钥证书:server.crt;
  • 服务器端私钥文件:server.key;
  • 客户端公钥证书:client.crt;
  • 客户端私钥文件:client.key;
  • 客户端集成证书(包罗公钥和私钥,用于欣赏器访问场景):client.p12;
  • 客户端集成证书(包罗公钥和私钥,用于Spring客户端访问场景):client.jks;
  • 服务端集成证书(包罗公钥和私钥,用于Spring服务端):localhost.jks;
  既然是双向验证,就必要双方的密钥,我们服务端称为server,而客户端称为client。
  天生这一些列证书之前,我们必要老师成一个CA根证书,然后由这个CA根证书颁发服务器公钥证书和客户端公钥证书。
  我们可以全程利用openssl来天生一些列的自署名证书,自署名证书没有听过证书机构的认证,很多欣赏器会以为不安全,但我们用来实验是充足的。必要在本机安装了openssl后才气继续本章的实验。
  2.1 天生根证书root.crt

  1. # 生成根证书私钥
  2. openssl genrsa -out root.key 1024
  3. # 根据私钥创建根证书请求文件,需要输入一些证书的元信息:邮箱、域名等
  4. openssl req -new -out root.csr -key root.key
  5. # 结合私钥和请求文件,创建根证书,有效期10年
  6. openssl x509 -req -in root.csr -out root.crt -signkey root.key -CAcreateserial -days 3650
复制代码
颠末上面三个下令行,我们终极可以得到一个署名有用期为10年的根证书root.crt,反面我们可以用这个根证书去颁发服务器证书和客户端证书。
  2.2 天生服务端证书server.crt和server.key

  1. # 创建服务端私钥
  2. openssl genrsa -out server.key 1024
  3. # 根据私钥生成请求文件
  4. openssl req -new -out server.csr -key server.key
  5. # 结合私钥和请求文件创建服务端证书,有效期10年
  6. openssl x509 -req -in server.csr -out server.crt -signkey server.key -CA ./root.crt -CAkey ./root.key -CAcreateserial -days 3650
复制代码
如果必要只必要摆设服务端证书端话,就可以竣事了。拿着server.crt公钥和server.key私钥摆设在服务器上,然后剖析域名到改服务器指向到IP,证书就摆设乐成了。
  2.3 天生客户端证书client.crt和client.key

  如果必要做双向验证的,也就是服务端要验证客户端证书的环境。那么必要在同一个根证书下再天生一个客户端证书。
  1. # 生成私钥
  2. openssl genrsa -out client.key 1024
  3. # 申请请求文件
  4. openssl req -new -out client.csr -key client.key
  5. # 生成证书
  6. openssl x509 -req -in client.csr -out client.crt -signkey client.key -CA ./root.crt -CAkey ./root.key -CAcreateserial -days 3650
复制代码
2.4 天生客户端PKCS12

  1. # 生成客户端集成证书pkcs12格式的文件,方便浏览器或者http客户端访问(密码:123456)
  2. openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12
复制代码
2.5 天生JKS

  Springboot项目中我们一样寻常利用jks格式的文件:
  1. openssl pkcs12 -export -clcerts -in server.crt -inkey server.key -out server.p12
  2. keytool -importkeystore -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass 123456 -alias server -deststorepass 123456 -destkeypass 123456 -destkeystore localhost.jks
  3. keytool -importkeystore -srckeystore client.p12 -srcstoretype PKCS12 -srcstorepass 123456 -alias server -deststorepass 123456 -destkeypass 123456 -destkeystore client.jks
复制代码
2.6 注意

  根证书的Common Name填写root就可以,客户端和服务器端的证书这个字段必要填写域名,肯定要注意的是,根证书的这个字段和客户端证书、服务器端证书不能一样。
  三、 步调设置

  3.1 Springboot整合双向验证

  1. server:
  2.   ssl:
  3.     enabled: false
  4.     key-store-type: JKS
  5.     key-store: localhost.jks
  6.     key-store-password: 123456
  7.     key-alias: localhost
  8.     client-auth: need
  9.     trust-store: localhost.jks
  10.     trust-store-type: JKS
  11.     trust-store-provider: SUN
  12.     trust-store-password: 123456
复制代码
3.2 Nginx设置

  有了上面的一些列证书,我们可以在Nginx服务器上设置双向认证的HTTPS服务了,具体设置方式如下:
  1. server {
  2.         listen       3001 ssl;
  3.         server_name  www.yourdomain.com;
  4.         ssl                  on;  
  5.         ssl_certificate      /data/sslKey/server.crt;  #server公钥证书
  6.         ssl_certificate_key  /data/sslKey/server.key;  #server私钥
  7.         ssl_client_certificate /data/sslKey/root.crt;  #根证书,可以验证所有它颁发的客户端证书
  8.         ssl_verify_client on;  #开启客户端证书验证  
  9.         location / {
  10.             root   html;
  11.             index  index.html index.htm;
  12.         }
  13.     }
复制代码
具体就是将服务器端的两个证书文件(server.crt/server.key)和根证书文件(root.crt)的路径设置到nginx的server节点设置中,而且把ssl_verify_client这个参数设置为on。
  有一点必要注意的就是,如果客户端证书不是由根证书直接颁发的,设置中还必要加一个设置:ssl_verify_depth 1.
  设置完成后,实验nginx -s reload重新加载下就见效了。
  3.3 利用curl作为客户端调用验证

  利用curl加上证书路径,可以直接测试Nginx的HTTPS双向认证是否设置乐成。下面我们测试三个用例:
  

  • 利用client.crt/client.key这一套客户端证书来调用服务器端;
  • 不利用证书来调用服务器端
  3.3.1 携带证书

  带证书的乐成调用:
  1. #--cert指定客户端公钥证书的路径
  2. #--key指定客户端私钥文件的路径
  3. #-k不校验证书的合法性,因为我们用的是自签名证书,所以需要加这个参数
  4. #可以使用-v来观察具体的SSL握手过程
  5. curl --cert ./client.crt --key ./client.key https://xxxxxx.com -k -v
复制代码
3.3.2 无证书

  1. curl https://xxxxx.com -k
  2. <html>
  3. <head><title>400 No required SSL certificate was sent</title></head>
  4. <body>
  5. <center><h1>400 Bad Request</h1></center>
  6. <center>No required SSL certificate was sent</center>
  7. <hr><center>nginx/1.17.5</center>
  8. </body>
  9. </html>
复制代码
利用根证书颁发的客户端证书可以正常发起双向HTTPS认证的调用。没有带客户端证书的调用会被服务器端拒绝服务。
  参考文章:
  [1] HTTPS双向认证指南
  [2] Https双向验证与Springboot整合测试-人来人往我只认你
  [3] SSL/TLS 双向认证(一) -- SSL/TLS 工作原理
  [4] Nginx证书设置:tomcat证书jks文件转nginx证书.cet和key文件
  [5] 自签SSL证书以及https的双向认证
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表