21

我正在尝试使用 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.

知道这个错误是什么意思吗?我该如何解决?

提前致谢,

4

2 回答 2

25

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

如果需要,请记住将客户端证书添加到服务器的信任库。

参考

于 2014-08-06T15:36:56.360 回答
9

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

我的 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。

于 2013-11-22T08:21:08.703 回答