如何在服务器端读取客户端发送的 TLS 证书?

How to read TLS certificate sent by a client on the server side?

我正在尝试使用 Curl 命令调用具有双向 TLS 的服务。

使用的卷曲命令:

curl -k -vvvv \
  --request POST \
  --header "Content-Type: application/json" \
  --cert client.pem:password \
  --key key.pem \
  "https://test.com:8443/testing"

我正在尝试找出以下内容:

  1. 我应该查看 server-side 以从 HTTP 请求中提取客户端证书的 HTTP 请求 header 是什么?

  2. 如果我无法从HTTP请求中提取服务器端的客户端证书,我可以在HTTP请求中添加自定义请求header并将客户端证书作为值发送吗那个习俗header?如果有人可以提供这种方法的示例,那就太好了。

客户端在使用双向 TLS 时发送 TLS 证书。

在双向 TLS 握手中,TLS 客户端证书不会在 HTTP header 中发送。它们作为握手期间交换的 TLS 消息的一部分由客户端传输,并且服务器在握手期间验证客户端证书。 mTLS 握手大致分为两部分,客户端验证并接受服务器证书,服务器验证并接受客户端证书。

如果客户端证书被接受,大多数网络服务器可以配置为添加 headers 用于将证书或证书中包含的信息传输到应用程序。环境变量在 Apache and Nginx 中填充了证书信息,可以在其他指令中用于设置 headers.

作为此方法的示例,以下 Nginx 配置片段将验证客户端证书,然后设置 SSL_CLIENT_CERT header 以将整个证书传递给应用程序。这将在证书成功验证时设置,因此应用程序随后可以解析证书并依赖其包含的信息。

server {
    listen 443 ssl;
    server_name example.com;
    ssl_certificate /path/to/chainedcert.pem;  # server certificate
    ssl_certificate_key /path/to/key;          # server key

    ssl_client_certificate /path/to/ca.pem;    # client CA
    ssl_verify_client on;
    proxy_set_header SSL_CLIENT_CERT $ssl_client_cert;

    location / {
        proxy_pass http://localhost:3000;
    }
}

我是这样做的:

curl -v \
  --key ./admin-key.pem \
  --cert ./admin.pem \
  https://xxxx/api/v1/