curl 命令 - 无法加载客户端证书 -8018
Posted
技术标签:
【中文标题】curl 命令 - 无法加载客户端证书 -8018【英文标题】:curl command - Unable to load client cert -8018 【发布时间】:2013-10-16 09:40:18 【问题描述】:我正在尝试使用 curl 命令通过代理连接到安全 Web 服务,但出现以下错误:
无法加载客户端证书 -8018。
完整的日志:
[e-ballo@myserver]# curl -v -x proxy01.net:8080 https://endPointURL.com/SOAP --key ./cert.crt --cert ./cert.crt -capath=/etc/pki/tls/certs
* About to connect() to proxy proxy01.net port 8080 (#0)
* Trying 10.0.3.64... connected
* Connected to proxy01.net (10.0.3.64) port 8080 (#0)
* Establish HTTP proxy tunnel to endPointURL.com:443
> CONNECT endPointURL.com:443 HTTP/1.1
> Host: endPointURL.com:443
> User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.3.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
> Proxy-Connection: Keep-Alive
>
< HTTP/1.0 200 Connection established
<
* Proxy replied OK to CONNECT request
* Initializing NSS with certpath: sql:/home/e-ballo/
* Unable to initialize NSS database
* Initializing NSS with certpath: none
* CAfile: /etc/pki/tls/certs/ca-bundle.crt
CApath: none
* Unable to load client cert -8018.
* NSS error -8018
* Closing connection #0
curl: (58) Unable to load client cert -8018.
知道这个错误是什么意思吗?我该如何解决?
提前致谢,
【问题讨论】:
【参考方案1】:我在 RHEL 6 上也遇到过这个问题。curl 是用 NSS 编译的,通过查看版本可以看到:
$ curl -V
curl 7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.14.3.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
Protocols: tftp ftp telnet dict ldap ldaps http file https ftps scp sftp
Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz
解决方案是向 curl 提供对存储您要使用的客户端证书的 NSS 数据库的引用。
创建证书
我从一个 Java 密钥库开始,它是使用此命令创建的(别名值将用于稍后引用证书):
keytool -genkeypair -alias myclient -keyalg RSA -keystore client_keystore.jks
现在,需要将此 JKS 密钥库转换为 pkcs12 格式:
keytool -importkeystore -srckeystore client_keystore.jks \
-destkeystore client_keystore.p12 -srcstoretype jks \
-deststoretype pkcs12
将证书导入 NSS 数据库
接下来,在您选择的目录中创建一个 NSS 数据库:
mkdir /home/user/nss
certutil -N -d /home/user/nss
此 certutil 命令创建 3 个 .db 文件,包括 cert8.db。这是“旧”数据库格式,但仍应有效。如果您需要创建 cert9.db 文件,请查看 certutil 文档。
使用pk12util将client_keystore.p12导入NSS数据库
pk12util -i client_keystore.p12 -d /home/user/nss
(可选)查看数据库中存储的证书:
certutil -L -d /home/user/nss -n myclient
使用来自 curl 的证书
证书现在可以被 curl 使用,但是我们需要让 curl 知道在哪里可以找到它。按照 curl 手册中的说明,创建一个 SSL_DIR 环境变量:
export SSL_DIR=/home/user/nss
最后是 curl 命令:
curl -vk --cert myclient https://localhost:8443/my/url
注意:这里指定了 -k 选项,因为服务器使用的是自签名证书。有关如何指定 cacert 的信息,请参阅 curl 手册。
如果需要,记得将客户端证书添加到服务器的信任库中。
参考
certutil and pk12util Documentation Point curl to Firefox's NSS database (~/.mozilla/firefox/[profile])【讨论】:
curl 的手册页说,即使 curl 是使用 NSS 构建的,也可以使用本地文件而不是 nss 昵称。If curl is built against the NSS SSL library then this option can tell curl the nickname of the certificate ... If you want to use a file from the current directory, please precede it with "./" prefix, in order to avoid confusion with a nickname.
需要把文件导入NSS数据库吗?【参考方案2】:
我已经解决了这个问题,所以我将发布解决方案。也许可以帮助某人。
我的 curl 版本是使用 Netscape 安全系统 (NSS) 库而不是 openSSL 库编译的。使用这两个库编译的 curl 版本使用不同的证书访问方法。我正在调用一个平面文件,这是 openSSL 方法。 另一种解决方案是安装 NSS(大多数 Red Hat 衍生产品上已经安装了 NSS)并创建一个 cert9.db 文件,导入您的证书和密钥(在使用 openssl 转换为 P12 之后 - 不要忘记添加“freindlyName”或昵称)使用 pk12util 进入该数据库。然后你通过它的昵称调用证书并提供数据库的密码。
另一个选项是使用 openssl 库获取或编译 curl 版本。 RedHat 5、ubuntu 或 windows 版本的 curl 通常已经以这种方式编译。 Red Hat 6 带有为 NSS 编译的 curl。
【讨论】:
我已经创建了数据库,导入了证书。并且能够通过命令行运行 curl。但是我需要做`export SSL_DIR=path。使用 php 时如何实现自动化?以上是关于curl 命令 - 无法加载客户端证书 -8018的主要内容,如果未能解决你的问题,请参考以下文章
PHP CURL“NSS:找不到客户端证书(未指定昵称)”问题