2024-03-21  阅读(3)
原文作者:小小工匠 原文地址: https://artisan.blog.csdn.net/article/details/136095672

202403212041435141.png


Pre

PKI - 借助Nginx 实现Https 服务端单向认证、服务端客户端双向认证

PKI - 数字签名与数字证书

PKI - 借助Nginx 实现Https_使用CA签发证书


概述

客户端使用自签名证书供服务端验证的作用和意义主要体现在以下几个方面:

  1. 身份验证: 自签名证书可以用于验证客户端的身份。通过客户端提供的证书,服务端可以确保连接方是合法的客户端,并且拥有该证书对应的私钥。
  2. 加密通信: 使用自签名证书的客户端可以与服务端建立加密的通信通道。客户端的证书中包含了公钥,可以用于加密数据传输,保护数据的机密性。
  3. 防止中间人攻击: 通过客户端的证书验证,服务端可以确保与客户端直接通信,防止中间人攻击。如果客户端提供的证书无效或不匹配,服务端会拒绝连接,从而保护通信的安全性。
  4. 授权访问: 服务端可以根据客户端提供的证书对其进行授权访问。通过证书中的信息,服务端可以确定客户端的身份和权限,从而限制或授权其访问特定资源或功能。
  5. 建立信任关系: 使用自签名证书的客户端可以建立信任关系,并证明其身份是可信的。服务端可以信任由特定 CA 签发的证书,从而确保与合法的客户端进行通信,建立信任关系。

总的来说,客户端使用自签名证书供服务端验证可以加强通信的安全性和可靠性,确保通信双方的身份和数据的安全,建立起信任关系,从而提高整体系统的安全性。


在 Nginx 中实现客户端使用自签名证书供服务器验证

要在 Nginx 中实现客户端使用自签名证书供服务器验证,需要执行以下步骤:

1. 生成客户端密钥对

    openssl genrsa -out client.key 2048

这个命令生成了一个 2048 位的 RSA 密钥对,其中私钥保存在 client.key 文件中。

2. 生成自签名客户端证书

    openssl req -x509 -new -nodes -key client.key -subj "/CN=client" -days 10000 -out client.crt

这个命令生成了一个自签名的客户端证书。
-x509 参数表示生成的证书是自签名的 X.509 证书,
-new 参数表示生成一个新的证书请求,
-nodes 参数表示不加密生成的私钥,
-key 参数指定了用于生成证书的私钥,
-subj 参数用于指定证书的主题信息,其中 /CN=client 表示通用名称 (Common Name) 是 “client”,
-days 参数表示证书的有效期
-out 参数指定了输出的证书文件名。

通过这些命令,成功生成了一个自签名的客户端证书和私钥,可以用于客户端与服务器之间的安全通信。

请注意,这些证书和密钥是自签名的,因此在生产环境中可能需要进行更严格的安全性配置。


3. 配置 Nginx

在 Nginx 的配置文件中,添加以下 SSL 配置,以指定客户端证书和 CA 证书,并启用客户端证书验证:

    server {
        listen 443 ssl;
    
       ssl on;
      ssl_certificate /cert/server.crt;
      ssl_certificate_key /cert/server.key;
      ssl_client_certificate /cert/client.crt;
      ssl_verify_client on;
    
      ssl_session_cache shared:SSL:1m;
      ssl_session_timeout 10m;
      ssl_ciphers HIGH:!aNULL:!MD5;
      ssl_prefer_server_ciphers on;
    
    
        ...
    }

以下是每一项的含义解释:

  1. ssl on;

    • 启用 SSL/TLS。这告诉 Nginx 对来自客户端的连接启用 SSL/TLS 加密。
  2. ssl_certificate /cert/server.crt;

    • 指定服务器证书的路径。server.crt 是服务器的公钥证书,用于向客户端证明服务器的身份。这个证书将由服务器发送给客户端,以供客户端验证服务器的身份。
  3. ssl_certificate_key /cert/server.key;

    • 指定服务器私钥的路径。server.key 是服务器的私钥,用于解密客户端发送的加密数据。私钥必须与证书配对,并且只有持有私钥的服务器才能解密使用相应证书加密的数据。
  4. ssl_client_certificate /cert/client.crt;

    • 指定客户端 CA 证书的路径。client.crt 是用于验证客户端证书的 CA 证书。当 ssl_verify_client on; 时,服务器将使用指定的客户端 CA 证书对客户端发送的证书进行验证。
  5. ssl_verify_client on;

    • 启用客户端证书验证。当此选项设置为 on 时,Nginx 将要求连接客户端提供有效的客户端证书,并使用 ssl_client_certificate 中指定的 CA 证书对其进行验证。
  6. ssl_session_cache shared:SSL:1m;

    • 配置 SSL 会话缓存。这指定了用于缓存 SSL 会话信息的共享内存区域的名称和大小。这可以提高 SSL/TLS 连接的性能,减少握手过程的开销。
  7. ssl_session_timeout 10m;

    • 设置 SSL 会话超时时间。这指定了 SSL 会话在多久没有被使用后过期并被删除的时间。过期的 SSL 会话将被移除,以释放资源。
  8. ssl_ciphers HIGH:!aNULL:!MD5;

    • 配置 SSL 密码套件。这指定了允许使用的密码套件列表。在这个例子中,使用了一个高安全性的密码套件,禁用了空密钥和 MD5 散列算法。
  9. ssl_prefer_server_ciphers on;

    • 设置是否优先使用服务器密码套件。当此选项设置为 on 时,服务器将优先选择服务器端指定的密码套件,而不是客户端指定的密码套件。这有助于防止客户端通过协商使用较弱的密码套件。

通过正确配置这些 SSL 选项,您可以提高您的 Nginx 服务器的安全性,并确保 SSL/TLS 连接的机密性和完整性。

通过这个配置,Nginx 将在客户端建立连接时要求客户端提供有效的证书,并使用指定的 CA 证书对其进行验证。只有当客户端提供的证书被成功验证后,Nginx 才会允许连接建立,并允许客户端访问受保护的资源。


4. 重启 Nginx 修

改完 Nginx 配置后,重新加载或重启 Nginx 服务,使更改生效。

    sudo systemctl reload nginx

现在,Nginx 已经配置为要求客户端使用自签名证书进行验证。当客户端发起连接时,Nginx 将验证客户端提供的证书是否由指定的 CA 签名,以及证书的有效性。如果验证通过,Nginx 将允许连接;否则,将拒绝连接。

请注意,客户端证书验证是双向的,即服务器会验证客户端提供的证书。因此,客户端在发起连接时需要提供有效的客户端证书和私钥。


5. 验证

执行

    cur1  https://artisan.com  --resolve artisan.com:443:192.68.3.103

返回

    <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.16.1</center>
    </body>
    </htm1>

服务器返回了一个 400 Bad Request 错误,指示客户端没有发送必需的 SSL 证书。这是因为服务器配置了要求客户端提供 SSL 证书,但客户端在连接时未提供有效的 SSL 证书。


如何解决呢?

可以通过以下几种方式来解决这个问题:

  1. 提供有效的客户端 SSL 证书: 确保客户端在连接时提供了有效的 SSL 证书。可以使用生成的客户端证书来进行连接。
  2. 检查 SSL 配置: 检查服务器端的 SSL 配置,确保已正确启用客户端证书验证,并且指定了正确的客户端 CA 证书路径。
  3. 调试连接: 可以使用 OpenSSL 工具来模拟客户端连接并进行调试,以查看服务器的 SSL 配置是否正确。例如,您可以使用以下命令进行连接:
        openssl s_client -connect artisan.com:443 -CAfile /path/to/ca.crt -cert /path/to/client.crt -key /path/to/client.key
其中,`/path/to/ca.crt` 是客户端 CA 证书的路径,`/path/to/client.crt` 和 `/path/to/client.key` 是客户端证书和私钥的路径。通过这个命令,您可以模拟客户端连接并查看服务器的 SSL 配置是否正确。
  1. 检查服务器日志: 检查服务器的日志文件,查看是否有关于 SSL 握手失败的错误消息。这些日志可以提供更多的细节,帮助您确定问题所在。

我们 提供有效的客户端 SSL 证书继续试下

    curl  https://artisan.com  --cacert /cert/ca.crt --cert /cert/client.crt --key  /cert/client.key --resolve artisan.com:443:192.168.3.103
  • --cacert /cert/ca.crt 客户端验证服务端用
  • --cert /cert/client.crt --key /cert/client.key 服务端验证客户端用 ,这个私钥不会发送给服务端,仅作为验证使用

OK, 可以正常访问。

在浏览器中安装客户端证书以便进行访问

完成双向认证后,如果想在浏览器中安装客户端证书以便进行访问,可以将客户端证书和私钥导出为 PKCS#12 格式 (PFX 文件),然后在浏览器中导入该文件。

下面是执行的步骤:

  1. 将客户端证书和私钥导出为 PKCS#12 格式:
    使用以下命令将客户端证书和私钥导出为 PKCS#12 格式的 PFX 文件:
        openssl pkcs12 -export -inkey /cert/client.key -in /cert/client.crt -out client.pfx
这个命令将 `client.crt` 和 `client.key` 文件导出到一个名为 `client.pfx` 的 PKCS\#12 文件中。
  1. 导入 PFX 文件到浏览器中:
    根据使用的浏览器不同,导入 PFX 文件的步骤可能会有所不同。一般来说,可以按照以下步骤来导入证书:

    • 在浏览器中打开设置或选项菜单。
    • 导航到安全性或证书管理部分。
    • 查找导入证书或安全令牌的选项,并选择导入。
    • 选择您之前导出的 client.pfx 文件,并输入密码(如果有的话)。
    • 完成导入后,浏览器将安装我们的客户端证书,并可以用于进行双向认证的访问。

通过执行这些步骤,浏览器就可以使用导入的客户端证书来进行与服务器的双向认证的安全通信。请注意,具体的操作步骤可能因浏览器版本和操作系统而有所不同,建议根据使用的浏览器和操作系统查阅相关文档以获取详细的指导。

    
    [root@localhost cert]# openssl pkcs12 -export -inkey /root/cert/client.key -in /root/cert/client.crt -out client.pfx
    Enter Export Password:
    Verifying - Enter Export Password:
    [root@localhost cert]#
    [root@localhost cert]# ll
    total 12
    -rw-r--r--. 1 root root 1090 Feb 11 15:14 client.crt
    -rw-r--r--. 1 root root 1675 Feb 11 15:13 client.key
    -rw-r--r--. 1 root root 2365 Feb 11 16:21 client.pfx
    [root@localhost cert]#
    [root@localhost cert]#
    [root@localhost cert]#

导入

202403212041437892.png

202403212041441593.png

202403212041446214.png

202403212041449855.png


Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文