Nginx 为 iPad 上的客户端证书提供“不支持的证书用途”,但相同的证书在桌面浏览器上可以正常工作?

Nginx 为 iPad 上的客户端证书提供“不支持的证书用途”,但相同的证书在桌面浏览器上可以正常工作?

我们公司的 Web 应用程序使用客户端证书进行身份验证。我们想添加一些 iPad 客户端来进行库存盘点等。客户端证书身份验证在桌面浏览器中运行良好,但当我们在 iPad 上使用与桌面浏览器完全相同的证书时,nginx 中会出现此错误:

7200#7200: *2 client SSL certificate verify error: (26:unsupported certificate purpose) while reading client request headers

Nginx 向 iPad 客户端返回 400 错误请求“SSL 证书错误”。

CA 公共证书和中级 CA 证书已安装在 iPad 上,也已安装在服务器上。同样,在我们的设置下,客户端证书身份验证在桌面浏览器上也能正常工作。

这是 iPad 的问题、nginx 的问题还是证书的问题?我们该如何排查和解决它?

更新更多信息

openssl x509 -purpose用于创建 pkcs 文件的证书是:

Certificate purposes:
SSL client : Yes
SSL client CA : No
SSL server : Yes
SSL server CA : No
Netscape SSL server : Yes
Netscape SSL server CA : No
S/MIME signing : Yes
S/MIME signing CA : No
S/MIME encryption : Yes
S/MIME encryption CA : No
CRL signing : Yes
CRL signing CA : No
Any Purpose : Yes
Any Purpose CA : Yes
OCSP helper : Yes
OCSP helper CA : No
Time Stamp signing : No
Time Stamp signing CA : No

...看起来是正确的。

用于创建pkcs文件的命令是:

openssl pkcs12 -export -out file.pk12 -inkey file.key -in file.crt -nodes -passout pass:mypassword

iPad 安装配置文件对话框声称身份证书未签名,但允许我安装它。

更新 2

可能的线索:

安装证书后,在 iPad 上查看证书详细信息时,iPad 会显示“已签名”,并列出证书本身的名称。在 Firefox 中查看证书时,Firefox 会在字段中显示正确的 CA。Issued By我不确定这是 iPad 故障还是证书签名不正确。

以下是用于创建和签署证书的确切代码(文件名已简化):

openssl genrsa -out file.key 4096

openssl req -new -key file.key -out file.csr -subj "$DN"

openssl x509 -req -days 365 -in file.csr -CA ca.crt -CAkey ca.key -set_serial $SerialNumber -out file.crt

openssl pkcs12 -export -out file.pk12 -inkey file.key -in file.crt -certfile ca.pem -nodes -passout pass:secret 2>&1

注意:$DN 和 $SerialNumber 由 PHP 生成,这里省略。ca.pem 是证书颁发机构的密钥和公共证书合并到一个文件中。

更新 3

我正在为来自 iPad 的请求添加 Nginx 错误日志的调试级别输出。公司名称和其他敏感信息已被替换为通用词语。

2017/02/19 14:17:37 [debug] 20917#20917: post event 000055D4E36D71A0
2017/02/19 14:17:37 [debug] 20917#20917: delete posted event 000055D4E36D71A0
2017/02/19 14:17:37 [debug] 20917#20917: accept on 0.0.0.0:443, ready: 1
2017/02/19 14:17:37 [debug] 20917#20917: posix_memalign: 000055D4E368EA20:512 @16
2017/02/19 14:17:37 [debug] 20917#20917: *94 accept: xx.xx.xx.xx:62856 fd:10
2017/02/19 14:17:37 [debug] 20917#20917: *94 event timer add: 10: 60000:1487531917179
2017/02/19 14:17:37 [debug] 20917#20917: *94 reusable connection: 1
2017/02/19 14:17:37 [debug] 20917#20917: *94 epoll add event: fd:10 op:1 ev:80002001
2017/02/19 14:17:37 [debug] 20917#20917: accept() not ready (11: Resource temporarily unavailable)
2017/02/19 14:17:37 [debug] 20917#20917: *94 post event 000055D4E36D7380
2017/02/19 14:17:37 [debug] 20917#20917: *94 delete posted event 000055D4E36D7380
2017/02/19 14:17:37 [debug] 20917#20917: *94 http check ssl handshake
2017/02/19 14:17:37 [debug] 20917#20917: *94 http recv(): 1
2017/02/19 14:17:37 [debug] 20917#20917: *94 https ssl handshake: 0x16
2017/02/19 14:17:37 [debug] 20917#20917: *94 SSL ALPN supported by client: spdy/3.1
2017/02/19 14:17:37 [debug] 20917#20917: *94 SSL ALPN supported by client: spdy/3
2017/02/19 14:17:37 [debug] 20917#20917: *94 SSL ALPN supported by client: http/1.1
2017/02/19 14:17:37 [debug] 20917#20917: *94 SSL ALPN selected: http/1.1
2017/02/19 14:17:37 [debug] 20917#20917: *94 SSL server name: "our.server.com"
2017/02/19 14:17:37 [debug] 20917#20917: *94 SSL_do_handshake: -1
2017/02/19 14:17:37 [debug] 20917#20917: *94 SSL_get_error: 2
2017/02/19 14:17:37 [debug] 20917#20917: *94 reusable connection: 0
2017/02/19 14:17:37 [debug] 20917#20917: *94 post event 000055D4E36D7380
2017/02/19 14:17:37 [debug] 20917#20917: *94 delete posted event 000055D4E36D7380
2017/02/19 14:17:37 [debug] 20917#20917: *94 SSL handshake handler: 0
2017/02/19 14:17:37 [debug] 20917#20917: *94 SSL_do_handshake: -1
2017/02/19 14:17:37 [debug] 20917#20917: *94 SSL_get_error: 2
2017/02/19 14:17:37 [debug] 20917#20917: *94 post event 000055D4E36D7380
2017/02/19 14:17:37 [debug] 20917#20917: *94 delete posted event 000055D4E36D7380
2017/02/19 14:17:37 [debug] 20917#20917: *94 SSL handshake handler: 0
2017/02/19 14:17:37 [debug] 20917#20917: *94 verify:0, error:26, depth:1, subject:"/CN=OUR-COMPANY Client CA/ST=State/C=US/O=OUR-COMPANY Client CA", issuer:"/C=US/ST=State/L=City/O=OUR-COMPANY, Inc/CN=OUR-COMPANY, Inc"
2017/02/19 14:17:37 [debug] 20917#20917: *94 verify:1, error:26, depth:2, subject:"/C=US/ST=State/L=City/O=OUR-COMPANY, Inc/CN=OUR-COMPANY, Inc", issuer:"/C=US/ST=State/L=City/O=OUR-COMPANY, Inc/CN=OUR-COMPANY, Inc"
2017/02/19 14:17:37 [debug] 20917#20917: *94 verify:1, error:26, depth:1, subject:"/CN=OUR-COMPANY Client CA/ST=State/C=US/O=OUR-COMPANY Client CA", issuer:"/C=US/ST=State/L=City/O=OUR-COMPANY, Inc/CN=OUR-COMPANY, Inc"
2017/02/19 14:17:37 [debug] 20917#20917: *94 verify:1, error:26, depth:0, subject:"/C=US/ST=State/L=City/O=OUR-COMPANY Client Certificate/CN=OUR-COMPANY-MUS-58A9EEA5", issuer:"/CN=OUR-COMPANY Client CA/ST=State/C=US/O=OUR-COMPANY Client CA"
2017/02/19 14:17:37 [debug] 20917#20917: *94 ssl new session: F89EA5F8:32:1533
2017/02/19 14:17:37 [debug] 20917#20917: *94 SSL_do_handshake: 1
2017/02/19 14:17:37 [debug] 20917#20917: *94 SSL: TLSv1.2, cipher: "ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH Au=RSA Enc=AESGCM(128) Mac=AEAD"
2017/02/19 14:17:37 [debug] 20917#20917: *94 reusable connection: 1
2017/02/19 14:17:37 [debug] 20917#20917: *94 http wait request handler
2017/02/19 14:17:37 [debug] 20917#20917: *94 malloc: 000055D4E3702330:1024
2017/02/19 14:17:37 [debug] 20917#20917: *94 SSL_read: -1
2017/02/19 14:17:37 [debug] 20917#20917: *94 SSL_get_error: 2
2017/02/19 14:17:37 [debug] 20917#20917: *94 free: 000055D4E3702330
2017/02/19 14:17:37 [debug] 20917#20917: *94 post event 000055D4E36D7380
2017/02/19 14:17:37 [debug] 20917#20917: *94 delete posted event 000055D4E36D7380
2017/02/19 14:17:37 [debug] 20917#20917: *94 http wait request handler
2017/02/19 14:17:37 [debug] 20917#20917: *94 malloc: 000055D4E3702330:1024
2017/02/19 14:17:37 [debug] 20917#20917: *94 SSL_read: 313
2017/02/19 14:17:37 [debug] 20917#20917: *94 SSL_read: -1
2017/02/19 14:17:37 [debug] 20917#20917: *94 SSL_get_error: 2
2017/02/19 14:17:37 [debug] 20917#20917: *94 reusable connection: 0
2017/02/19 14:17:37 [debug] 20917#20917: *94 posix_memalign: 000055D4E369B8A0:4096 @16
2017/02/19 14:17:37 [debug] 20917#20917: *94 http process request line
2017/02/19 14:17:37 [debug] 20917#20917: *94 http request line: "GET / HTTP/1.1"
2017/02/19 14:17:37 [debug] 20917#20917: *94 http uri: "/"
2017/02/19 14:17:37 [debug] 20917#20917: *94 http args: ""
2017/02/19 14:17:37 [debug] 20917#20917: *94 http exten: ""
2017/02/19 14:17:37 [debug] 20917#20917: *94 posix_memalign: 000055D4E3703F20:4096 @16
2017/02/19 14:17:37 [debug] 20917#20917: *94 http process request header line
2017/02/19 14:17:37 [debug] 20917#20917: *94 http header: "Host: our.server.com"
2017/02/19 14:17:37 [debug] 20917#20917: *94 http header: "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
2017/02/19 14:17:37 [debug] 20917#20917: *94 http header: "Accept-Language: en-us"
2017/02/19 14:17:37 [debug] 20917#20917: *94 http header: "Connection: keep-alive"
2017/02/19 14:17:37 [debug] 20917#20917: *94 http header: "Accept-Encoding: gzip, deflate"
2017/02/19 14:17:37 [debug] 20917#20917: *94 http header: "User-Agent: Mozilla/5.0 (iPad; CPU OS 9_3_5 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Mobile/13G36"
2017/02/19 14:17:37 [debug] 20917#20917: *94 http header done
2017/02/19 14:17:37 [info] 20917#20917: *94 client SSL certificate verify error: (26:unsupported certificate purpose) while reading client request headers, client: xx.xx.xx.xx, server: our.server.com, request: "GET / HTTP/1.1", host: "our.server.com"
2017/02/19 14:17:37 [debug] 20917#20917: *94 http finalize request: 495, "/?" a:1, c:1
2017/02/19 14:17:37 [debug] 20917#20917: *94 event timer del: 10: 1487531917179
2017/02/19 14:17:37 [debug] 20917#20917: *94 http special response: 495, "/?"
2017/02/19 14:17:37 [debug] 20917#20917: *94 http set discard body
2017/02/19 14:17:37 [debug] 20917#20917: *94 xslt filter header
2017/02/19 14:17:37 [debug] 20917#20917: *94 HTTP/1.1 400 Bad Request
Server: nginx
Date: Sun, 19 Feb 2017 19:17:37 GMT
Content-Type: text/html
Content-Length: 224
Connection: close

答案1

可能的答案:iPad 的受信任 CA 存储中有一个中间 CA 证书(用于签署客户端证书的证书)。当我从 iPad 中删除中间 CA 时,客户端证书能够与 Nginx 一起使用。我还尝试在桌面 Firefox 中将中间 CA 安装为受信任的 CA,但安装后不久,我在 Firefox 客户端中收到了来自 Nginx 的相同错误。

因此,虽然证书现在有效,但我很困惑为什么信任颁发客户端证书的 CA 会破坏它们。

由于我仍有赏金要颁发,因此我将把赏金颁发给能够做到以下任一事情的人:

  1. 利用支持文档解释为什么这是正常/预期的行为。

-或者-

  1. 如果这不正常,请告诉我是什么配置错误导致了这种奇怪的行为。

答案2

Nginx 不允许使用具有SSL server : Yes角色的客户端身份验证证书。

相关内容