尝试使用客户端证书时解决sslv3警报握手失败问题

时间:2016-04-02 07:48:33

标签: ssl curl openssl client-certificates

我正在尝试连接到需要证书进行授权的服务。过程是我向服务发送CSR文件。该服务签署CSR并向我发送我用于连接的证书。

  1. 我通过以下命令行生成CSR:

    openssl req -new -nodes -newkey rsa:2048 -keyout cert.key -out cert.csr
    
  2. 我获取了cert.csr的内容并发送给他们。他们生成了客户端证书,我收回了一份PEM文件。

  3. 我现在尝试使用SSLCERT中的证书文件连接curl()并将cert.key中的私钥提供为CURLOPT_SSLKEY - (我在步骤1中获得)。

  4. 失败:error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure

  5. 在这个过程中我做错了什么?

    当我尝试收到包含服务中的私钥(自签名证书)的测试证书时,

    可行。但是,当我使用他们从我的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

4 个答案:

答案 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)

不是一个明确的答案,但是太多不适合评论:

我假设他们给了你一个证书,证明要么有错误的发行人(虽然他们的服务器可以使用更具体的警报代码)或错误的主题。我们知道证书与您的私钥相匹配 - 因为curlopenssl 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

所以我做了以下事情:

  1. 将三个证书文件的内容合并成一个名为 all.pem 的文件:
cat cert1.pem chain1.pem fullchain1.pem > all.pem
  1. 创建包含完整证书链的密钥库:
openssl pkcs12 -export -in all.pem -inkey privkey1.pem -out my_keystore.p12 -name mycertalias -CAfile chain1.pem -caname root