我正在尝试将客户端证书与 curl 结合使用。如果我使用针对 openssl 或 libressl 构建的 curl 二进制文件,则它可以正常工作。如果我使用使用 libnss 构建的 curl,则它会拒绝加载密钥并出现错误SEC_ERROR_BAD_KEY
。是否可以将这种类型的密钥与 curl+libnss 结合使用?
所讨论的私钥是 EC 密钥。我使用的密钥文件看起来像是可以使用命令生成的密钥文件openssl ecparam -name prime256v1 | openssl ecparam -genkey
。此示例密钥与我正在使用的密钥类型相同(但出于显而易见的原因,它不是我的实际密钥)。这不是受密码保护的密钥。
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIDNhB9ml7mqEB0hHZpXkvG+TtAYKMpY87JsYdGzERmCVoAoGCCqGSM49
AwEHoUQDQgAEE/vPWzL6zPAkYQWGGJFnQwEJ6otQsI9Crqhek9KuvNRtFh73IJbp
U9NgcqNnRZf9vwaS8VWTBViDcufIsyuaxg==
-----END EC PRIVATE KEY-----
已知的 curl 工作命令(来自 ubuntu 18.04 存储库)
$ curl --version
curl 7.58.0 (x86_64-pc-linux-gnu) libcurl/7.58.0 OpenSSL/1.1.1 zlib/1.2.11 libidn2/2.0.4 libpsl/0.19.1 (+libidn2/2.0.4) nghttp2/1.30.0 librtmp/2.3
Release-Date: 2018-01-24
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets HTTPS-proxy PSL
$ curl -v --cacert ./ca.pem --cert ./cert.pem --key ./key.pem https://192.168.73.51:443/_ping
* Trying 192.168.73.51...
* TCP_NODELAY set
* Connected to 192.168.73.51 (192.168.73.51) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: ./ca.pem
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Request CERT (13):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS handshake, CERT verify (15):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN, server accepted to use h2
* Server certificate:
* subject: OU=ucp; CN=system:ucp:w581z5f7ny14uuz2zqvdvlmgy
* start date: Sep 12 18:45:00 2019 GMT
* expire date: Dec 11 18:45:00 2019 GMT
* subjectAltName: host "192.168.73.51" matched cert's IP address!
* issuer: CN=UCP Client Root CA
* SSL certificate verify ok.
* Using HTTP2, server supports multi-use
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x55da2b525580)
这是使用相同的 ca.pem、cert.pem 和 key.pem 文件的相同命令,但使用 centos 7 curl+libnss 二进制文件:
$ curl --version
curl 7.29.0 (x86_64-redhat-linux-gnu) libcurl/7.29.0 NSS/3.36 zlib/1.2.7 libidn/1.28 libssh2/1.4.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp scp sftp smtp smtps telnet tftp
Features: AsynchDNS GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL libz unix-sockets
$ curl -v --cacert ./ca.pem --cert ./cert.pem --key ./key.pem https://192.168.73.51:443/_ping
* About to connect() to 192.168.73.51 port 443 (#0)
* Trying 192.168.73.51...
* Connected to 192.168.73.51 (192.168.73.51) port 443 (#0)
* Initializing NSS with certpath: sql:/etc/pki/nssdb
* CAfile: ./ca.pem
CApath: none
* unable to load client key: -8178 (SEC_ERROR_BAD_KEY)
* NSS error -8178 (SEC_ERROR_BAD_KEY)
* Peer's public key is invalid.
* Closing connection 0
curl: (58) unable to load client key: -8178 (SEC_ERROR_BAD_KEY)