我正在尝试连接到需要证书进行授权的服务。过程是我向服务发送CSR文件。该服务签署CSR并向我发送我用于连接的证书。
我通过以下命令行生成CSR:
openssl req -new -nodes -newkey rsa:2048 -keyout cert.key -out cert.csr
我获取了cert.csr的内容并发送给他们。他们生成了客户端证书,我收回了一份PEM文件。
我现在尝试使用SSLCERT中的证书文件连接curl()并将cert.key中的私钥提供为CURLOPT_SSLKEY - (我在步骤1中获得)。
失败:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
在这个过程中我做错了什么?
当我尝试收到包含服务中的私钥(自签名证书)的测试证书时,可行。但是,当我使用他们从我的CSR生成的证书然后使用我的私钥作为密钥时,它会因握手失败而出错。
所以我知道它与openssl / curl不支持v3 / TLS等有关。其他人在研究解决方案时发现了他们的问题。
以下是我的观点:
curl -i -v --request POST https://service.com/ --cert clientcert.pem --key private_key.pem --cert-type pem --tlsv1.1 --insecure
* Connected to service.com (1xx.xxx.xxx.xx) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Request CERT (13):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS handshake, CERT verify (15):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS alert, Server hello (2):
* error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
* Closing connection 0
运行以下版本:curl 7.35.0(x86_64-pc-linux-gnu)libcurl / 7.35.0 OpenSSL / 1.0.1f zlib / 1.2.8 libidn / 1.28 librtmp / 2.3
答案 0 :(得分:5)
什么SSL私钥应与客户端证书一起发送?
他们都没有:)
关于客户端证书的一个吸引人的地方是,它不会做愚蠢的事情,比如将纯文本中的秘密(如密码)传输到服务器(HTTP basic_auth
)。密码仍然用于解锁客户端证书的密钥,它只是在交换期间不直接使用或tp验证客户端。
相反,客户端为该会话选择临时随机密钥。然后客户端用他的证书签署临时随机密钥并将其发送到服务器(一些人放弃)。如果一个坏人拦截任何东西,它是随机的,所以它不能在将来使用。它甚至不能用于服务器的第二次协议运行,因为服务器也会选择一个新的随机值。
失败:错误:14094410:SSL例程:SSL3_READ_BYTES:sslv3警报握手失败
使用TLS 1.0及以上版本;并使用Server Name Indication。
您尚未提供任何代码,因此我不清楚如何告诉您该怎么做。相反,这里是OpenSSL命令行来测试它:
openssl s_client -connect www.example.com:443 -tls1 -servername www.example.com \
-cert mycert.pem -key mykey.pem -CAfile <certificate-authority-for-service>.pem
您还可以使用-CAfile
来避免“验证错误:num = 20”。例如,请参阅“verify error:num=20” when connecting to gateway.sandbox.push.apple.com。
答案 1 :(得分:4)
不是一个明确的答案,但是太多不适合评论:
我假设他们给了你一个证书,证明要么有错误的发行人(虽然他们的服务器可以使用更具体的警报代码)或错误的主题。我们知道证书与您的私钥相匹配 - 因为curl
和openssl client
都将它们配对而没有抱怨不匹配;但我们实际上并不知道它与所需的CA匹配 - 因为你的curl使用openssl和openssl SSL客户端并不强制配置的客户端证书与certreq.CAs匹配。
对于有效的测试P12的证书,请openssl x509 <clientcert.pem -noout -subject -issuer
和相同。做openssl s_client
(或检查你做的那个)并查看Acceptable client certificate CA names
;那里的名字或其中一个名称应该与您的证书的发行人(确切地!)相匹配。如果没有,那很可能是您的问题,您需要与他们核实,您已将CSR提交到正确的地方并以正确的方式提交。也许他们在不同的地区或业务线,或测试与产品,或活跃与未决等方面有不同的制度。
如果您的证书的发行人确实符合所需的CA,请将其主题与工作(test-P12)进行比较:它们的格式是否相似?工作中的任何组件是否存在于您的组件中?如果他们允许,请尝试生成并提交一个新的CSR,其主题名称与test-P12完全相同,或尽可能接近,并查看是否产生更好的证书。 (您不必生成新的密钥来执行此操作,但如果您选择,请跟踪哪些证书与哪些密钥相匹配,以免您将其混淆。 )如果没有帮助查看带有openssl x509 <cert -noout -text
的证书扩展,以了解可能与主题授权相关的任何差异,例如KeyUsage,ExtendedKeyUsage,可能是Policy,也许是Constraints,甚至可能是非标准的东西
如果所有其他方法都失败了,请询问服务器运营商他们的日志对问题的评价,或者您是否有权访问自己的日志。
答案 2 :(得分:1)
在CentOS 8系统上,对我来说,解决方案是通过验证 / etc / crypto-policies / config 读取默认值 DEFAULT 来检查系统密码策略。比其他任何值都重要。
将此值更改为 DEFAULT 后,请运行以下命令:
/usr/bin/update-crypto-policies --set DEFAULT
重新运行curl命令,它应该可以工作。
答案 3 :(得分:0)
就我而言,错误的原因是我只将证书(例如 cert1.pem
)和私钥(例如 privkey1.pem
)导入密钥库并解决了问题,我还必须导入完整的证书链。
我从“Let's Encrypt”证书颁发机构获得了以下文件:
privkey1.pem
fullchain1.pem
chain1.pem
cert1.pem
所以我做了以下事情:
all.pem
的文件:cat cert1.pem chain1.pem fullchain1.pem > all.pem
openssl pkcs12 -export -in all.pem -inkey privkey1.pem -out my_keystore.p12 -name mycertalias -CAfile chain1.pem -caname root