curl 无法检索 HTTPS 内容:错误:14094410:SSL 例程:ssl3_read_bytes:sslv3 警报握手失败

curl 无法检索 HTTPS 内容:错误:14094410:SSL 例程:ssl3_read_bytes:sslv3 警报握手失败

我尝试https://www.lawsociety.com.au在 Windows 10 和 Ubuntu 16.04 上使用 curl 访问网站。它在 Ubuntu 上可以运行,但在 Windows 上会失败并显示消息error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure。我不确定哪里出了问题以及如何修复它。

以下是 Windows 机器上的 curl 输出:

> curl -i -v -I https://www.lawsociety.com.au
* Rebuilt URL to: https://www.lawsociety.com.au/
*   Trying 125.7.104.7...
* TCP_NODELAY set
* Connected to www.lawsociety.com.au (125.7.104.7) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
*   CAfile: D:\dev\curl\bin\curl-ca-bundle.crt
  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS alert, Server hello (2):
* error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure
* stopped the pause stream!
* Closing connection 0
curl: (35) error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure

卷曲版本:

curl 7.57.0 (x86_64-pc-win32) libcurl/7.57.0 OpenSSL/1.1.0g (WinSSL) zlib/1.2.11 WinIDN libssh2/1.8.0 nghttp2/1.28.0
Release-Date: 2017-11-29
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: AsynchDNS IDN IPv6 Largefile SSPI Kerberos SPNEGO NTLM SSL libz TLS-SRP HTTP2 HTTPS-proxy MultiSSL    

Ubuntu 上的相同命令:

$ curl -I -v https://www.lawsociety.com.au
* Rebuilt URL to: https://www.lawsociety.com.au/
*   Trying 125.7.104.7...
* Connected to www.lawsociety.com.au (125.7.104.7) port 443 (#0)
* found 148 certificates in /etc/ssl/certs/ca-certificates.crt
* found 594 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* SSL connection using TLS1.0 / RSA_3DES_EDE_CBC_SHA1
*        server certificate verification OK
*        server certificate status verification SKIPPED
*        common name: *.lawsociety.com.au (matched)
*        server certificate expiration date OK
*        server certificate activation date OK
*        certificate public key: RSA
*        certificate version: #3
*        subject: C=AU,postalCode=2000,ST=NSW,L=Sydney,street=170 Phillip Street,O=THE LAW SOCIETY OF NEW SOUTH WALES,OU=PremiumSSL Wildcard,CN=*.lawsociety.com.au
*        start date: Fri, 17 Mar 2017 00:00:00 GMT
*        expire date: Mon, 16 Apr 2018 23:59:59 GMT
*        issuer: C=GB,ST=Greater Manchester,L=Salford,O=COMODO CA Limited,CN=COMODO RSA Organization Validation Secure Server CA
*        compression: NULL
* ALPN, server did not agree to a protocol
> HEAD / HTTP/1.1
> Host: www.lawsociety.com.au
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Date: Tue, 26 Dec 2017 09:04:02 GMT
Date: Tue, 26 Dec 2017 09:04:02 GMT
< Server: Oracle-Application-Server-11g
Server: Oracle-Application-Server-11g
< Cache-Control: no-cache
Cache-Control: no-cache
< Content-Length: 36272
Content-Length: 36272
< Set-Cookie: JSESSIONID=kGs3hCQCW7FPhQ2Lh0JvKn9JvXhhHCK2GQKXvLps308Ww1D70pMp!1826685759; path=/; HttpOnly
Set-Cookie: JSESSIONID=kGs3hCQCW7FPhQ2Lh0JvKn9JvXhhHCK2GQKXvLps308Ww1D70pMp!1826685759; path=/; HttpOnly
< X-ORACLE-DMS-ECID: 005OJeGQSZb9xWGayxQ_MG0007Z60000EU
X-ORACLE-DMS-ECID: 005OJeGQSZb9xWGayxQ_MG0007Z60000EU
< X-Powered-By: Servlet/2.5 JSP/2.1
X-Powered-By: Servlet/2.5 JSP/2.1
< Content-Type: text/html; charset=utf-8
Content-Type: text/html; charset=utf-8

<
* Connection #0 to host www.lawsociety.com.au left intact

openssl s_client在 Windows 上尝试过命令:

> openssl s_client -connect www.lawsociety.com.au:443
CONNECTED(00000224)
depth=3 C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root
verify error:num=19:self signed certificate in certificate chain
---
Certificate chain
 0 s:/C=AU/postalCode=2000/ST=NSW/L=Sydney/street=170 Phillip Street/O=THE LAW SOCIETY OF NEW SOUTH WALES/OU=PremiumSSL Wildcard/CN=*.lawsociety.com.au
   i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Organization Validation Secure Server CA
 1 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Organization Validation Secure Server CA
   i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
 2 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
   i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
 3 s:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
   i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
---
Server certificate
-----BEGIN CERTIFICATE-----
... <removed to save space> ...
-----END CERTIFICATE-----
subject=/C=AU/postalCode=2000/ST=NSW/L=Sydney/street=170 Phillip Street/O=THE LAW SOCIETY OF NEW SOUTH WALES/OU=PremiumSSL Wildcard/CN=*.lawsociety.com.au
issuer=/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Organization Validation Secure Server CA
---
No client certificate CA names sent
---
SSL handshake has read 5683 bytes and written 621 bytes
---
New, TLSv1/SSLv3, Cipher is RC4-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1
    Cipher    : RC4-SHA
    Session-ID: 8198FE887E4FC12D68E2388D4C052ABF
    Session-ID-ctx:
    Master-Key: 93688C15A75E3E9F596AF96DFF72B557AD28A3FEF8764401CBD12D1F432EAF4D216595D74338AF24498AB29FF5ABE759
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1514278771
    Timeout   : 300 (sec)
    Verify return code: 19 (self signed certificate in certificate chain)
---

因此连接似乎没问题。在浏览器中打开 URL 也一切正常。

我错过了什么?

更新

1.其中一个可能的问题是该网站使用的是过时的 RC4-SHA 密码。我尝试使用 curl 明确启用它,但 curl 拒绝了它:

> curl -i -v -I --ciphers "RC4-SHA" https://www.lawsociety.com.au
* Rebuilt URL to: https://www.lawsociety.com.au/
*   Trying 125.7.104.7...
* TCP_NODELAY set
* Connected to www.lawsociety.com.au (125.7.104.7) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* failed setting cipher list: RC4-SHA
* Closing connection 0
curl: (59) failed setting cipher list: RC4-SHA

2.另一个潜在问题是根证书可能不可用。不过,curl 附带了最新的 Mozilla CA 包 ( curl-ca-bundle.crt),因此我相信它使用的是正确的证书。

我还将所有公共证书从工作的 Ubuntu 机器复制到 Windows 机器,并使用--capath参数将证书路径指定给 curl - 但这没有帮助。

3.为了完整起见,我尝试使用最新的 Python 3.6.4:

import urllib.request
with urllib.request.urlopen('https://www.lawsociety.com.au/') as u:
    print(u.read())

Python SSL 应该使用 Windows 的 HTTPS 功能。但是,它失败并出现相同的错误:

ssl.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:777)
...
During handling of the above exception, another exception occurred:
...
urllib.error.URLError: <urlopen error [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:777)>

因此,问题似乎不在于缺少证书,而是在更早的某个地方发生的。我不是 SSL 专家,所以我可能是错的。

解决方案

问题的根本原因是网站使用的 SSL 协议和密码过时了。为了让 curl 正常工作,我将其降级为使用 OpenSSL 1.0.2 的版本,该版本仍然支持 RC4 密码。之后一切都运行正常。

对于那些需要 Python 解决方案的人:

import ssl
import urllib.request

ctx = ssl.SSLContext(protocol=ssl.PROTOCOL_SSLv3)
ctx.set_ciphers('SSLv3')
# alternatively, for this particular website:
#ctx.set_ciphers('RC4-SHA:RC4-MD5')

with urllib.request.urlopen('https://www.lawsociety.com.au/', context=ctx) as u:
    print(u.read())

答案1

我相信这里实际上有两个有点重叠的问题,都与服务器显然过时或疯狂操作有关。ssllabs 的分析显示它仅支持 SSLv3 和 TLSv1.0 协议,以及仅四种密码套件:

TLS_RSA_WITH_DES_CBC_SHA (0x9)   INSECURE   56
TLS_RSA_WITH_3DES_EDE_CBC_SHA (0xa)   WEAK  112
TLS_RSA_WITH_RC4_128_MD5 (0x4)   INSECURE   128
TLS_RSA_WITH_RC4_128_SHA (0x5)   INSECURE   128

(在 OpenSSL 命名方案中分别为 DES-CBC-SHA、DES-CBC3-SHA、RC4-MD5 和 RC4-SHA)。

首先,正如 SSLLabs 所指出的,服务器“版本不兼容”;如果你向它发送 ClientHello 提供 1.0 以上的版本在版本 1.0 的记录中(并且其他方面都可以接受)它会协商降低到 1.0,这是应该的*,但是如果您发送此优惠时记录版本为 1.1 或 1.2,就像某些软件那样(但 AFAICT 任何最近的 OpenSSL 都不会这样做),服务器会中止并发出警报 close_notify(这对于此状态是不正确的)。(*:嗯,因为它应该支持 1.0)

其次,它仅支持上述四种密码套件。OpenSSL 的最新版本(特别是 1.1.0g)不再支持单 DES(完全不支持),因为它完全失效了,也不支持 RC4 或三重 DES默认情况下因为各种偏见普通生日攻击;因此,如果使用 OpenSSL,则没有共同的密码套件,服务器会正​​确中止并发出警报 handshake_failure。但应该可以启用 RC4 和/或 TDES,除非它们在构建(编译)时配置了。我注意到您的 Windows 版本显示(WinSSL) 此外OpenSSL/1.1.0g;我不知道这是否意味着这里使用了 schannel(或者根本没有使用),在这种情况下,这可能是--ciphers RC4-SHA(使用 OpenSSL 命名方案)不起作用的原因。

请注意,Windows 程序,尤其是 curl 和 OpenSSL 等“导入”程序,通常不会像 Unbuntu 和大多数 Linux(以及其他 Unix)那样共享库。您可以openssl version在 Windows OpenSSL 上尝试查看它是哪一个;我敢打赌它不是最新的,如果您获得最新版本,它会在命令行中显示相同的问题。

Ubuntu 16.04(我认为是 LTS?)不是最前沿的,它仍然支持最近才弃用的密码是有道理的。

答案2

问题出在网站的哈希算法和密码上。至少 RC4 很久以前就被宣布为不安全,所以很多程序都拒绝使用它。此外,一些 SHA 算法也不安全。实际的密码代码可能已从软件中完全删除。

--- 上一个错误答案 ---

您的 Windows OpenSSL 版本缺少用于验证远程服务器的 TLS 证书的受信任的根证书。

这是 Windows CURL 中加载验证证书的行:

* successfully set certificate verify locations:
*   CAfile: D:\dev\curl\bin\curl-ca-bundle.crt

Linux 中也有类似的条目:

* found 148 certificates in /etc/ssl/certs/ca-certificates.crt
* found 594 certificates in /etc/ssl/certs

发生这种情况是因为 Windows OpenSSL 不支持 Windows 证书存储,您必须在那里手动安装证书。

https://maulwuff.de/research/ssl-debugging.html#hdr3.3有关于该问题及其解决方法的一些信息。

答案3

我遇到过类似的问题。此消息错误“cURL 错误 35:错误:14094410:SSL 例程:ssl3_read_bytes:sslv3 警报握手失败(http_request_failed)“出现在 wordpress 上。

我正在尝试配置喷气背包WordPress的我正在使用云闪付

我可以点击按钮来修复它启用通用 SSL在 CloudFlare 上。

答案4

通过在 ssl-params.conf 上添加 TLSv1.3 参数解决了我的问题。

ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;

相关内容