Nginx开启TLS双向认证流程及配置

1. 认证流程

双向认证流程图
双向认证流程说明:

  1. 客户端发起连接
    客户端首先向服务器发送ClientHello消息,其中包含以下信息:
    • 支持的协议版本和加密套件列表
    • 客户端随机数
  2. 服务器响应
    服务器响应客户端的ClientHello消息,并发送ServerHello消息,其中包含以下信息:
    • 服务器选择的协议版本和加密套件
    • 服务器随机数
    • 服务器证书链
  3. 客户端验证服务器证书
    客户端验证服务器证书链的有效性,包括检查证书是否由受信任的CA签发、证书是否有效以及证书中的主机名是否与服务器的主机名匹配。
  4. 客户端发送客户端证书(如果需要)
    如果服务器要求客户端进行身份验证,客户端会将自己的证书和客户端KeyProof消息发送给服务器。客户端KeyProof消息包含客户端使用服务器公钥加密的预主密钥。
  5. 服务器验证客户端证书(如果需要)
    服务器验证客户端证书的有效性,类似于客户端验证服务器证书的过程。服务器还会使用客户端公钥解密客户端KeyProof消息中的预主密钥。
  6. 双方计算共享会话密钥
    客户端和服务器使用各自的预主密钥、客户端随机数和服务器随机数来计算共享的会话密钥。
  7. 客户端发送ChangeCipherSpec消息
    客户端向服务器发送ChangeCipherSpec消息,指示服务器开始使用共享会话密钥加密通信。
  8. 服务器发送ChangeCipherSpec消息
    服务器向客户端发送ChangeCipherSpec消息,指示客户端开始使用共享会话密钥加密通信。
  9. 双方发送ApplicationData消息
    客户端和服务器可以使用共享会话密钥加密和解密ApplicationData消息,其中包含应用程序数据。

2. 客户端Nginx配置

server {
  listen 25300 http2;
  http2_body_preread_size 256m;

  access_log  /var/log/nginx/client/access.log;
  error_log   /var/log/nginx/client/error.log;

  location / {
    grpc_pass grpcs://127.0.0.1:25400;

    grpc_ssl_certificate                ca/client.crt;    # 客户端证书
    grpc_ssl_certificate_key            ca/client.key;    # 客户端私钥
    grpc_ssl_trusted_certificate        ca/server-ca.crt; # 可信服务端CA证书
    grpc_ssl_verify                     on;               # 开启双向认证
    grpc_ssl_verify_depth               2;                # 证书验证深度

    proxy_http_version 1.1;
    grpc_set_header x-ptp-session-id "00000000000000010000000000000001";

    proxy_set_header Host                $host:$server_port;
    proxy_set_header X-Real-IP           $remote_addr;
  }
}

3. 服务端Nginx配置

server {
  listen 25400 ssl http2;
  http2_body_preread_size 256m;

  ssl_certificate                ca/server.crt;  # 服务端端证书
  ssl_certificate_key            ca/server.key;  # 服务端私钥
  ssl_trusted_certificate        ca/client.crt;  # 指定可信客户端CA证书
  ssl_client_certificate         ca/client.crt;  # 客户端CA证书
  ssl_verify_client              on;             # 开启证书验证

  access_log  /var/log/nginx/server/access.log;
  error_log   /var/log/nginx/server/error.log;

  location / {
    grpc_pass grpc://127.0.0.1:5400;
    proxy_http_version 1.1;

    proxy_set_header Host                $host:$server_port;
    proxy_set_header X-Real-IP           $remote_addr;
  }
}​

附录1:生成证书

参考另一篇文章:Nginx证书生成(CA证书、服务器私钥、服务器证书)

附录2:参考链接

附录3:名词解释

主密钥

在TLS握手过程中,主密钥是客户端和服务器共同协商生成的一个用于加密通信数据的对称密钥。它由以下几种随机数共同生成:

  • 客户端随机数:客户端生成的随机数。
  • 服务器随机数:服务器生成的随机数。
  • 预主密钥(可选):客户端使用服务器的公钥加密的随机数。

具体步骤如下:

  1. 客户端和服务器在握手过程中各自生成一个随机数,称为客户端随机数服务器随机数
  2. 客户端向服务器发送客户端随机数预主密钥(如果使用预主密钥)。
  3. 服务器收到客户端随机数预主密钥后,使用其私钥解密预主密钥(如果使用预主密钥)。
  4. 客户端和服务器使用以下公式共同生成主密钥
    主密钥 = PRF(客户端随机数 || 服务器随机数 || 预主密钥)
    其中,PRF是一个伪随机函数,用于将输入数据映射到一个随机的输出值。

主密钥用于生成以下加密密钥:

  • 会话密钥:用于加密和解密通信数据。
  • 消息认证码(MAC):用于确保数据完整性。

主密钥具有以下特点:

  • 对称性:客户端和服务器使用相同的主密钥加密和解密数据。
  • 安全性主密钥是随机生成的,因此很难被破解。
  • 临时性主密钥只用于一次TLS会话,在会话结束后丢弃。

预主密钥是一种可选的优化方案,可以减少握手的长度。它通常用于客户端和服务器之间已经建立了信任的情况下。

以下是一些关于主密钥的常见问题:

  • 主密钥的长度是多少?
    主密钥的长度通常为256位,但这取决于所使用的密码套件。

  • 主密钥是否会存储在客户端或服务器上?
    主密钥是临时性的,只在会话期间存在,不会存储在客户端或服务器上。

  • 如果主密钥被泄露,会有什么后果?
    如果主密钥被泄露,攻击者可能会窃听或篡改通信数据。

  • 31
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值