握手期间"tlsv1警告内部错误"

Ale*_*kov 14 php ssl openssl

我有一个PHP脚本来检查URL的可用性(基本上,当URL可以在浏览器中打开时,脚本应该对给定的URL返回true,反之亦然).有一个我偶然发现的网址:https://thepiratebay.gd/.此URL可以在浏览器中正确打开,但fsockopen()只会因SSL握手错误而失败.在PHP中调试fsockopen()的选项并不多,但是在深入挖掘它时,我发现我也无法使用console openssl client 连接到https://thepiratebay.gd/:

openssl s_client -connect thepiratebay.gd:443 
CONNECTED(00000003)
39613:error:14077438:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert internal error:/SourceCache/OpenSSL098/OpenSSL098-50/src/ssl/s23_clnt.c:602:
Run Code Online (Sandbox Code Playgroud)

这个网站似乎使用网络浏览器或卷曲打开,但是,我无法找到通过openssl连接到它的方法.显然,服务器使用TLS 1.2和ECDHE-ECDSA-AES128-GCM-SHA256密码,但即使我强制使用openssl,它仍然会失败:

openssl s_client -cipher ECDHE-ECDSA-AES128-GCM-SHA256 -connect thepiratebay.gd:443 -tls1_2
CONNECTED(00000003)
140735195829088:error:14094438:SSL routines:SSL3_READ_BYTES:tlsv1 alert internal error:s3_pkt.c:1256:SSL alert number 80
140735195829088:error:1409E0E5:SSL routines:SSL3_WRITE_BYTES:ssl handshake failure:s3_pkt.c:596:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 7 bytes and written 0 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : 0000
    Session-ID: 
    Session-ID-ctx: 
    Master-Key: 
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1432931347
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---
Run Code Online (Sandbox Code Playgroud)

我尝试了各种openssl版本:0.9.8y,1.0.1g,以及最新的0.9.8zf和1.0.2a.我还尝试在至少5台服务器(CentOS,Debian,OSX)上运行它,但没有运气.

似乎每个其他网站都处理得很好,以下是成功握手输出的示例:

openssl s_client -connect stackoverflow.com:443  -tls1
CONNECTED(00000003)
depth=1 /C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
verify error:num=20:unable to get local issuer certificate
verify return:0
---
Certificate chain
 0 s:/C=US/ST=NY/L=New York/O=Stack Exchange, Inc./CN=*.stackexchange.com
   i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
 1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
   i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIGajCCBVKgAwIBAgIQCn1PE//Ffo4Be8tPBlsAZDANBgkqhkiG9w0BAQsFADBw
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNz
dXJhbmNlIFNlcnZlciBDQTAeFw0xMzEwMjIxMjAwMDFaFw0xNjA3MDYxMjAwMDBa
MGoxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJOWTERMA8GA1UEBxMITmV3IFlvcmsx
<---skipped few lines--->
qOHCjaUIx7vKszN4cqbvyry/NdxYkPCC7S8Eks8NjSyppzRL79tU0Yr1MUhVEd6h
GjB2qDwvAGqyWmLz1Q/l82lZbXyBF26DVTJ3RFRUzzieyzKucaVgohI7HC2yyJ9Y
AsE7wvVK4odQI3fRjOsLRaXjFtpiaor0rERUxM4mg7jj05leRBkSazNjv2xvCL5/
Qqm5PN666tREQwvgvXZgg+ZlKWkFyOq6X3THstM6CC8DTGED0cb94WPQA4YTp9OQ
rS3+OedQN+Nlu80Sk8Y=
-----END CERTIFICATE-----
subject=/C=US/ST=NY/L=New York/O=Stack Exchange, Inc./CN=*.stackexchange.com
issuer=/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
---
No client certificate CA names sent
---
SSL handshake has read 3956 bytes and written 426 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES128-SHA
    Session-ID: 2E38670F2CABEF3D65FAC67DB6D2E00DBACA4519E50B463D57FCFF8410640BF5
    Session-ID-ctx: 
    Master-Key: 4C63E5502FF7DD36853048E775435A76CB1FDEB37104D6714B1C37D89482D8111B93574D2B3D7F38A1EEFF85D69F9F54
    Key-Arg   : None
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket:
    0000 - 39 a8 c2 5f c5 15 04 b3-20 34 af fe 20 8e 4d 6c   9.._.... 4.. .Ml
    0010 - 6e 63 f1 e3 45 fd 2a 2c-d9 3c 0d ac 11 ab c0 c9   nc..E.*,.<......
    0020 - ce 51 19 89 13 49 53 a0-af 87 89 b0 5d e2 c5 92   .Q...IS.....]...
    0030 - af e5 84 28 03 4e 1e 98-4c a7 03 d5 5f fc 15 69   ...(.N..L..._..i
    0040 - 7c 83 d2 98 7d 42 50 31-30 00 d7 a8 3c 85 88 a7   |...}BP10...<...
    0050 - cd c0 bb 45 c8 12 b1 c8-4b 76 3c 41 5e 47 04 b5   ...E....Kv<A^G..
    0060 - 60 67 22 76 60 bb 44 f3-4b 3d 3d 99 af 0e dd 0d   `g"v`.D.K==.....
    0070 - 13 95 db 94 90 c2 0f 47-26 04 65 6b 71 b2 f8 1c   .......G&.ekq...
    0080 - 31 95 82 8b 00 38 59 08-1e 84 80 dc da 04 5c f0   1....8Y.......\.
    0090 - ae cc 2b ac 55 0f 39 59-0b 39 7d c7 16 b9 60 ef   ..+.U.9Y.9}...`.

    Start Time: 1432930782
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
Run Code Online (Sandbox Code Playgroud)

很难相信所有这些openssl版本都有相同的bug,所以我认为我做错了.

任何人都可以建议如何使用openssl连接到这个特定的网站?

jww*_*jww 12

这两个是一个糟糕的组合:

-cipher ECDHE-ECDSA-AES128-GCM-SHA256
Run Code Online (Sandbox Code Playgroud)

和:

error:/SourceCache/OpenSSL098/OpenSSL098-50/src/ssl/s23_clnt.c
Run Code Online (Sandbox Code Playgroud)

OpenSSL 0.9.8没有完整的EC支持.它不支持TLS 1.1或1.2.要获得AEAD密码套件,您需要使用TLS 1.2.这意味着您需要OpenSSL 1.0.0或更高版本(IIRC).

OpenSSL 1.0.1和1.0.2都有它们,因此最好使用这些版本.


 openssl s_client -connect thepiratebay.gd:443 ...
Run Code Online (Sandbox Code Playgroud)

您正在寻找的命令是:openssl s_client -connect thepiratebay.gd:443 -tls1_2 -servername thepiratebay.gd -CAfile XXX.-servername征集SNI.

当我点击该站点时,该服务器已通过AddTrust External CA Root认证.当您访问该网站时,它已通过DigiCert High Assurance EV Root CA认证.当您再次访问该网站时,它已获得COMODO ECC认证中心的认证.

不同的CA和配置与负载均衡器后面的分布式站点对话,每个参与的Web服务器的配置略有不同.


除了多个Web服务器和配置之外,还有一些Web服务器本身配置错误.它们配置错误,因为它们不发送构建验证路径所需的链.

链应包括(1)服务器证书; (2)构成"根"链的从属CA或中间体.对于(2),可以存在一种或多种中间体.

链应该包括根.您必须拥有root,并且必须信任它.


这个网站似乎使用网络浏览器或卷曲打开,但是,我无法找到通过openssl连接到它的方法...

这是因为由于Web服务器配置错误,浏览器会携带数百个根CA和从属CA的列表:)该列表包括AddTrust外部CA根,DigiCert高保证EV根CACOMODO ECC根证书颁发机构.


任何人都可以建议如何使用openssl连接到这个特定的网站?

好的,对于OpenSSL命令,您应该使用-CAfile.通常,您只需使用类似的东西openssl s_client -connect ... -CAfile DigiCertHighAssuranceEVRootCA.crt(对于通过DigiCert High Assurance EV Root CA认证的服务器).但在这种情况下,这不起作用.

您必须使用所需的根和从属CA创建单个文件.该文件应该是构建验证服务器证书路径所需的PEM格式的根CA和从属CA的串联.看起来它至少需要3或4个证书.

或者,您可以放弃构建自己的文件,并使用类似的东西cacert.pem.但使用CA Zoo存在一些风险(我对他们的深情术语).对于某些风险,请参阅cacert.pem我的计算机是否独一无二?.

以编程方式,您将SSL_CTX_load_verify_locations在OpenSSL中使用.然后传递连接的PEM文件CAfile.

我不确定你会在PHP中使用什么.


相关,cacert.pem有155个根和下属.其中大多数不需要认证网站thepiratebay.gd:

$ cat cacert.pem | grep BEGIN | wc -l
     155
Run Code Online (Sandbox Code Playgroud)

因此,您希望将您的限制CAfile仅限于认证网站所需的那些原因.


(评论)不确定这是正确的问题,但现在我想知道是否有办法以编程方式跳过这些检查以减少漏报的数量...

我可能不会放弃支票.既然您已经了解了正在发生的事情,那么使用系统应该更容易,而不是放弃它.

重申一下,要么:

  1. 仅使用必要的根和从属CA.

    1. 你构建它,连接PEM证书
    2. 创建文件 piratebay-certs.pem
    3. 添加必要的CA.
  2. 将CA Zoo与预定义的受信任的根和从属CA一起使用

    1. 你下载它
    2. cacert.pem

第三种选择是让站点修复其Web服务器配置.但如果现在还没有发生,它可能不会发生.(这可能是一个设计决策 - 该网站可能正在使用多个CA来确保没有一个CA可以对网站进行操作.但这并不能解决不完整的链).


更一般的观察:

我有一个PHP脚本来检查URL可用性(基本上,当URL可以在浏览器中打开时,脚本应该为给定的URL返回true,反之亦然

piratebay.gd特别是远离检查随机URL,你可能不得不使用cacert.pem.那是因为100万个站点的随机样本可能会使用所有这些站点.

如果piratebay.gd仍然失败,那么找出缺少的东西cacert.pem,然后:

cat cacert.pem > my-expanded-cacert.pem
cat missing-cert.pem >> my-expanded-cacert.pem
Run Code Online (Sandbox Code Playgroud)


Mal*_*ick 6

由于不同的原因,我收到了相同的错误消息:许多服务器都在使用SNI,这可能会产生此错误。

在我的情况下(使用 boost_asio + openssl 制作的 C++ 客户端)我使用以下代码修复了它:

 char port[] =  "https";
 string host =  "www.server.com"
 boost::asio::ip::tcp::resolver::query query(host, port);
 ...
 boost::asio::ssl::context ctx(boost::asio::ssl::context::tlsv12);
 ...
 ...
 //the following line fix the issue
 SSL_set_tlsext_host_name(socket_.native_handle(), host_.c_str());
Run Code Online (Sandbox Code Playgroud)

另请参阅此 SO 答案