cURL不尊重TLS v1

时间:2015-10-26 15:37:17

标签: android ssl curl ssl-certificate

我无法连接到仅限TLS的后端。配置如下:

  • 客户端:带有curl版本的Android设备(Moto X gen 2,Android 5.1):

    curl 7.21.3 (arm-unknown-eabi) libcurl/7.21.3 OpenSSL/1.0.1j zlib/1.2.8
    Protocols: http https 
    Features: IPv6 NTLM SSL libz
    
  • 服务器:通配符证书(DigiCert SHA2安全服务器CA),后端接受TLS 1.0或更高版本 - 仅限。

在OS X中使用cURL 7.43.0时,连接正常,因为客户端尊重服务器的最高TLS版本:

curl -vvv -X GET -o /dev/null https://domain
* Rebuilt URL to: https://domain
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying ip...
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0* Connected to domain (ip) port 443 (#0)
* TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
* Server certificate: *.domain
* Server certificate: DigiCert SHA2 Secure Server CA
* Server certificate: DigiCert Global Root CA
  0     0    0     0    0     0      0      0 --:--:--  0:00:01 --:--:--     0> GET / HTTP/1.1
> Host: domain
> User-Agent: curl/7.43.0
> Accept: */*
> 
< HTTP/1.1 200 OK

但Android没有运气。由于不接受SSLv3连接,因此传递--tlsv1选项。仍然,客户端选择使用SSLv3,因此无法结束握手:

curl -vvv --tlsv1 -X GET https://domain                                                                                                                                                             
* About to connect() to domain port 443 (#0)
*   Trying ip... connected
* Connected to domain (ip) 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 alert, Server hello (2):
* SSL certificate problem, verify that the CA cert is OK. Details:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
* Closing connection #0

相同的结果,但未指定TLS 1.0:curl -vvv -X GET https://domain

有什么方法可以告诉客户端使用TLS而不是SSLv3?

编辑:检查已接受的答案,因为这是一种真正检查cURL在您的设备中执行操作的好方法。问题本身是由于证书没有附加完整链(中间+根证书)而引起的。以下是一些可以帮助您进一步调试问题的在线SSL健康检查程序:

https://www.ssllabs.com/ssltest/

https://www.digicert.com/help/

1 个答案:

答案 0 :(得分:1)

  
      
  • SSLv3,TLS握手,客户端问候(1):
  •   

虽然看起来使用了SSLv3,但可能没有使用它。 OpenSSL在SSLv3函数中实现了大部分TLS1.x协议,因为TLS1.x只是更好的SSLv3,并且协议差别不大。

为了测试这个,我设置了一个简单的服务器,它回复了密码和协议版本,它在卷曲方面提供:

$ curl -vvv --tlsv1 -o /dev/null --insecure  https://127.0.0.1:12345
...
* SSLv3, TLS handshake, Client hello (1):
} [data not shown]
* SSLv3, TLS handshake, Server hello (2):
{ [data not shown]
* SSLv3, TLS handshake, CERT (11):
{ [data not shown]
* SSLv3, TLS handshake, Server key exchange (12):
{ [data not shown]
* SSLv3, TLS handshake, Server finished (14):
{ [data not shown]
* SSLv3, TLS handshake, Client key exchange (16):
} [data not shown]
* SSLv3, TLS change cipher, Client hello (1):
} [data not shown]
* SSLv3, TLS handshake, Finished (20):
} [data not shown]
* SSLv3, TLS change cipher, Client hello (1):
{ [data not shown]
* SSLv3, TLS handshake, Finished (20):
{ [data not shown]
* SSL connection using ECDHE-RSA-AES128-GCM-SHA256

但在服务器端:

cipher=ECDHE-RSA-AES128-GCM-SHA256 version=TLSv1_2
GET / HTTP/1.1
User-Agent: curl/7.35.0
Host: 127.0.0.1:12345
Accept: */*

因此,即使调试输出显示SSLv3,它实际上也是TLS1.2。