首页 > 其他分享 >https双向认证

https双向认证

时间:2024-12-21 13:41:33浏览次数:8  
标签:https crt 证书 认证 client key 双向 server 客户端

一、https双向认证原理

双向认证流程

  1. 客户端发起建立HTTPS连接请求,将SSL协议版本的信息发送给服务端;
  2. 服务器端将本机的公钥证书(server.crt)发送给客户端;
  3. 客户端读取公钥证书(server.crt),取出了服务端公钥;
  4. 客户端将客户端公钥证书(client.crt)发送给服务器端;
  5. 服务器端使用根证书(root.crt)解密客户端公钥证书,拿到客户端公钥;
  6. 客户端发送自己支持的加密方案给服务器端;
  7. 服务器端根据自己和客户端的能力,选择一个双方都能接受的加密方案;
  8. 使用客户端的公钥加密. 后发送给客户端;
  9. 客户端使用自己的私钥解密加密方案,生成一个随机数R,使用服务器公钥加密后传给服务器端;
  10. 服务端用自己的私钥去解密这个密文,得到了密钥R
  11. 服务端和客户端在后续通讯过程中就使用这个密钥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

# 生成根证书私钥
openssl genrsa -out root.key 1024

# 根据私钥创建根证书请求文件,需要输入一些证书的元信息:邮箱、域名等
openssl req -new -out root.csr -key root.key

# 结合私钥和请求文件,创建根证书,有效期10年
openssl x509 -req -in root.csr -out root.crt -signkey root.key -CAcreateserial -days 3650

经过上面三个命令行,我们最终可以得到一个签名有效期为10年的根证书root.crt,后面我们可以用这个根证书去颁发服务器证书和客户端证书。

2.2 生成服务端证书server.crtserver.key

# 创建服务端私钥
openssl genrsa -out server.key 1024

# 根据私钥生成请求文件
openssl req -new -out server.csr -key server.key

# 结合私钥和请求文件创建服务端证书,有效期10年
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.crtclient.key

如果需要做双向验证的,也就是服务端要验证客户端证书的情况。那么需要在同一个根证书下再生成一个客户端证书。

# 生成私钥
openssl genrsa -out client.key 1024

# 申请请求文件
openssl req -new -out client.csr -key client.key

# 生成证书
openssl x509 -req -in client.csr -out client.crt -signkey client.key -CA ./root.crt -CAkey ./root.key -CAcreateserial -days 3650

2.4 生成客户端PKCS12

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

2.5 生成JKS

Springboot项目中我们一般使用jks格式的文件:

openssl pkcs12 -export -clcerts -in server.crt -inkey server.key -out server.p12

keytool -importkeystore -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass 123456 -alias server -deststorepass 123456 -destkeypass 123456 -destkeystore localhost.jks

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整合双向验证

server:
  ssl:
    enabled: false
    key-store-type: JKS
    key-store: localhost.jks
    key-store-password: 123456
    key-alias: localhost
    client-auth: need
    trust-store: localhost.jks
    trust-store-type: JKS
    trust-store-provider: SUN
    trust-store-password: 123456

3.2 Nginx配置

有了上面的一些列证书,我们可以在Nginx服务器上配置双向认证的HTTPS服务了,具体配置方式如下:

server {
        listen       3001 ssl;
        server_name  www.yourdomain.com;
        ssl                  on;  
        ssl_certificate      /data/sslKey/server.crt;  #server公钥证书
        ssl_certificate_key  /data/sslKey/server.key;  #server私钥
        ssl_client_certificate /data/sslKey/root.crt;  #根证书,可以验证所有它颁发的客户端证书
        ssl_verify_client on;  #开启客户端证书验证  

        location / {
            root   html;
            index  index.html index.htm;
        }
    }

具体就是将服务器端的两个证书文件(server.crt/server.key)和根证书文件(root.crt)的路径配置到nginxserver节点配置中,并且把ssl_verify_client这个参数设置为on

有一点需要注意的就是,如果客户端证书不是由根证书直接颁发的,配置中还需要加一个配置:ssl_verify_depth 1.

配置完成后,执行nginx -s reload重新加载下就生效了。

3.3 使用curl作为客户端调用验证

使用curl加上证书路径,可以直接测试NginxHTTPS双向认证是否配置成功。下面我们测试三个用例:

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

带证书的成功调用:

#--cert指定客户端公钥证书的路径
#--key指定客户端私钥文件的路径
#-k不校验证书的合法性,因为我们用的是自签名证书,所以需要加这个参数
#可以使用-v来观察具体的SSL握手过程

curl --cert ./client.crt --key ./client.key https://xxxxxx.com -k -v
3.3.2 无证书
curl https://xxxxx.com -k
<html>
<head><title>400 No required SSL certificate was sent</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<center>No required SSL certificate was sent</center>
<hr><center>nginx/1.17.5</center>
</body>
</html>

使用根证书颁发的客户端证书可以正常发起双向HTTPS认证的调用。没有带客户端证书的调用会被服务器端拒绝服务。

参考文章:

[1] HTTPS双向认证指南

[2] Https双向验证与Springboot整合测试-人来人往我只认你

[3] SSL/TLS 双向认证(一) -- SSL/TLS 工作原理

[4] Nginx证书配置:tomcat证书jks文件转nginx证书.cetkey文件

[5] 自签SSL证书以及https的双向认证

标签:https,crt,证书,认证,client,key,双向,server,客户端
From: https://www.cnblogs.com/zyly/p/18614684

相关文章

  • https://github.com/mvysny/vok-helloworld-app修改内容
    build.gradle.kts:importorg.gradle.api.tasks.testing.logging.TestExceptionFormatimportorg.jetbrains.kotlin.gradle.dsl.JvmTargetimportorg.jetbrains.kotlin.gradle.tasks.KotlinCompileplugins{kotlin("jvm")version"2.1.0"......
  • 深入解析:Nginx通过一个域名配置多个HTTPS项目的实现与优化
    目录引言Nginx基础知识什么是NginxNginx的核心功能多项目部署的需求分析实现一个域名配置多个项目准备工作配置HTTPS的基本步骤配置多个项目的两种方式Nginx配置文件详解基于路径区分项目基于子域名区分项目HTTPS配置中的注意事项证书生成与管理多项目使用单一证书......
  • 泷羽sec之OSCP认证:OSCP认证介绍与备考少踩坑经验
    声明:本套OSCP培训课程为泷羽sec付费课程。b站上的红队从0到1免费。学习视频来自B站up主**泷羽sec**有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关,切勿触碰法律底线......
  • 信创适配证书、兼容性互认证书、信创产品认证证书有什么区别?
    一、三种信创证书有哪些区别?1、信创适配认证证书:发证单位:由适配中心发放;目的:证明产品在信创环境中可以安装和卸载,即证明产品“能不能用”。性质:属于企业之间的证书,主要是证明产品基本可用性。2、兼容性互认证书:常见厂商:如鲲鹏、麒麟等。目的:针对特定CPU或操作系统,证明......
  • 微信代开发小程序,认证及备案一步搞定
    大家好,我是小悟。为了帮助第三方服务商更方便快捷地为小程序完成认证和备案,平台提供认证及备案二合一能力。商家只需上传一次申请信息,即可同步发起认证及备案业务申请。认证审核通过后自动流转备案审核,减少商家重复上传证件和重复授权操作。将认证信息做成模板化管理,这样......
  • 如何在 Vue 中集成第三方身份认证服务?
    在Vue.js中集成第三方身份认证服务(如Google、Facebook或Twitter等)通常涉及以下几个步骤:选择认证服务:决定你要集成的第三方认证服务。常见的服务提供商有FirebaseAuthentication、Auth0、Okta等,它们提供了易于使用的SDK和API来处理用户认证。注册应用:......
  • 12.17双向链表和循环链表
    1.思维导图2.单向循环链表1>程序代码:头文件:#ifndef__LOOPLINK_H__#define__LOOPLINK_H__#include<stdio.h>#include<stdlib.h>//构造节点数据类型typedefintDatatype;typedefstructnode{ union { intlen; Datatypedata; }; structnode*next;}......
  • C# 自定义JWT 仿写认证
    1、系统已经有了JWT了,认证冲突。publicclassMyJwt{privateconststringSecretKey="YourSecretKeyHere";//创建类似JWT的令牌publicstaticstringCreateToken(List<Claim>claims){varheader="{\......
  • 在java中调用不信任的https接口
    如何在java中调用不安全的https接口主要由两部分构成忽略SSL证书校验并声明协议为TLSv1.3禁用主机名验证下面的代码为Post实现,分别为传递body和传递表单包含文件。java17使用的java.net,java8使用的javax.net一个简单的分析方式使用wireshark抓取对应的接口的日志,以及开......
  • C语言单向循环链表和双向循环链表
     单向循环链表#ifndef__TEST_H__#define__TEST_H__#include<stdio.h>#include<stdlib.h>typedefintdataType;typedefstructnode{ union { intlen; dataTypedata; }; structnode*next;}loopLink,*looplinkPtr;looplinkPtrcreat();intemp......