curl命令 - 无法加载客户端证书 -8018

24

我正在尝试使用curl命令通过代理连接到安全的webservice,但是我收到以下错误信息:

无法加载客户端证书-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.
任何想法这个错误是什么意思?我该怎么修复它?
谢谢提前。
2个回答

29

我也在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手册。

如果需要,请将客户端证书添加到服务器的信任存储中。

参考资料


curl的手册中说,即使使用NSS构建了curl,也可以使用本地文件而不是NSS昵称。 如果curl是针对NSS SSL库构建的,则此选项可以告诉curl证书的昵称...如果要使用当前目录中的文件,请在其前面加上“./”前缀,以避免与昵称混淆。 我们需要将文件导入NSS数据库吗? - spkvn

10

我已经解决了这个问题,所以我将发布解决方案。也许可以帮助到某些人。

我的curl版本是使用Netscape安全系统(NSS)库编译的,而不是使用openSSL库。使用这两个库编译的curl版本使用不同的证书访问方法。我正在调用一个平面文件,这是openSSL方法。 另一个解决方案是安装NSS(大多数Red Hat衍生版中已经存在),并创建一个cert9.db文件,使用pk12util导入您的证书和密钥(在使用openssl转换为P12之后-不要忘记添加“friendlyName”或昵称)。然后通过它的昵称调用证书并提供db的密码。

另一种选择是获取或编译使用openssl库的curl版本。RedHat 5、ubuntu或Windows版本的curl经常已经以这种方式编译。Red Hat 6附带使用NSS编译的curl。


2
我已经创建了数据库,导入了证书,并能够通过命令行运行curl。但是当使用PHP时,我需要执行“export SSL_DIR={path}”。我该如何自动化这个过程? - Severino Lorilla Jr.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接