如何在php中为curl添加密码



我试图使用php curl连接到一个网站,但得到错误"没有常见的加密算法"。进一步调查,我认为这和国家安全保障局有关?我发现,从命令行,我可以重现错误(所以问题肯定是在curl中,而不是在php包装器中),但是如果我设置—ciphers ecdhe_ecdsa_aes_128_sha,那么它就可以工作了:

[ec2-user@ip-10-181-165-22 current]$ curl -I https://sslspdy.com
curl: (35) Cannot communicate securely with peer: no common encryption algorithm(s).
[ec2-user@ip-10-181-165-22 current]$ curl -I --ciphers ecdhe_ecdsa_aes_128_sha https://sslspdy.com
HTTP/1.1 200 OK
Server: nginx centminmod
Content-Type: text/html; charset=utf-8
Connection: close
Vary: Accept-Encoding
Strict-Transport-Security: max-age=31536000; includeSubdomains
Date: Sat, 07 Feb 1970 22:34:32 GMT
X-Page-Speed: ngx_pagespeed
Cache-Control: max-age=0, no-cache

我的问题是,

  1. 为什么会发生这种情况?我没能在网上找到一个解释ssl密码是如何在curl中工作的;似乎每一页都是假设读者已经是该领域的专家——不幸的是,像"你可能正在使用NSS,所以尝试将PKCS转换为FIPS"这样的句子对我来说是完全无法理解的,并且谷歌只能解释单个组件(通常是参考20年前的标准),而不是它们之间的关系。

  2. 是否有任何方法可以让curl告诉我它正在尝试哪些密码,服务器将接受哪些密码?我试着在ssllabs上查找服务器,但它似乎说服务器接受所有密码,这显然不是。

  3. 我需要传递什么选项到curl_setopt,以便我的php脚本能够连接到这个服务器?

  4. 如果我设置这个密码,会破坏其他网站吗?我能做些什么,使curl能够连接到所有的安全站点,或者我必须手动迭代不同的密码尝试每一个,以找出哪一个工作?

    为什么会发生这种情况?我没能在网上找到ssl密码在curl中如何工作的解释。

这取决于一些事情。客户端和服务器库、客户端和服务器配置等。你需要提供更多的细节。


  • 有没有办法让curl告诉我哪些密码
  • 使用合适的工具。在本例中,它是一个更新的sslscan


    我需要传递什么选项到curl_setopt,以便我的php脚本能够连接到这个服务器?

    CURLOPT_SSL_CIPHER_LIST .


  • 如果我将密码设置为此,会破坏其他网站吗?
  • 也许。这取决于特定站点的配置。

    理想情况下,您选择12或16个您认可的密码套件,然后使用它们而不是一个。12或16涵盖了你在互联网上遇到的大多数网站。

    这是我通常使用的列表。它从哪个密码套件启用SSL套接字?:

    • TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
    • TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
    • TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
    • TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
    • TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
    • TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
    • TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
    • TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
    • TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
    • TLS_DHE_RSA_WITH_AES_128_CBC_SHA
    • TLS_DHE_DSS_WITH_AES_128_CBC_SHA
    • TLS_RSA_WITH_AES_256_CBC_SHA256
    • TLS_RSA_WITH_AES_256_CBC_SHA
    • TLS_RSA_WITH_AES_128_CBC_SHA256
    • TLS_RSA_WITH_AES_128_CBC_SHA

    我想放弃TLS_RSA_*密码套件,因为它们是密钥传输,但我需要它们用于我遇到的那些旧的IIS服务器。

    从下面的扫描结果可以看出,这个列表与服务器的列表相交。


    注意,您没有指定,说TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384。相反,在OpenSSL中,您为套件指定OpenSSL的名称ECDHE-ECDSA-AES256-SHA384。您可以在OpenSSL密码的文档中找到OpenSSL名称。

    在OpenSSL中,您也可以使用字符串"HIGH:!aNULL:!MD5:!RC4:!PSK:!SRP"。这样你就能得到大约40到50个相当不错的选择。

    您可以运行OpenSSL ciphers命令查看列表:

    $ openssl ciphers -v 'HIGH:!aNULL:!MD5:!RC4:!PSK:!SRP'
    ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(256) Mac=AEAD
    ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(256) Mac=AEAD
    ECDHE-RSA-AES256-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA384
    ECDHE-ECDSA-AES256-SHA384 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(256)  Mac=SHA384
    ECDHE-RSA-AES256-SHA    SSLv3 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA1
    ECDHE-ECDSA-AES256-SHA  SSLv3 Kx=ECDH     Au=ECDSA Enc=AES(256)  Mac=SHA1
    ...
    

    您可以使用sslscan的更新版本来确定可用的密码套件:

    $ sslscan --no-failed sslspdy.com
    ...
    Testing SSL server sslspdy.com on port 443
      Supported Server Cipher(s):
        Accepted  TLSv1  256 bits  ECDHE-ECDSA-AES256-SHA
        Accepted  TLSv1  128 bits  ECDHE-ECDSA-AES128-SHA
        Accepted  TLSv1.1  256 bits  ECDHE-ECDSA-AES256-SHA
        Accepted  TLSv1.1  128 bits  ECDHE-ECDSA-AES128-SHA
        Accepted  TLSv1.2  256 bits  ECDHE-ECDSA-AES256-GCM-SHA384
        Accepted  TLSv1.2  256 bits  ECDHE-ECDSA-AES256-SHA384
        Accepted  TLSv1.2  256 bits  ECDHE-ECDSA-AES256-SHA
        Accepted  TLSv1.2  128 bits  ECDHE-ECDSA-AES128-GCM-SHA256
        Accepted  TLSv1.2  128 bits  ECDHE-ECDSA-AES128-SHA256
        Accepted  TLSv1.2  128 bits  ECDHE-ECDSA-AES128-SHA
      Prefered Server Cipher(s):
        TLSv1  128 bits  ECDHE-ECDSA-AES128-SHA
        TLSv1.1  128 bits  ECDHE-ECDSA-AES128-SHA
        TLSv1.2  128 bits  ECDHE-ECDSA-AES128-GCM-SHA256
    

    我没能在网上找到ssl密码如何在curl中工作的解释;…

    这不是curl所特有的。使用SSL/TLS,客户端提供它愿意使用的密码,服务器从这些密码中选择它也支持的密码。默认情况下,客户端不会提供所有可以提供的密码,特别是那些被认为是弱的密码。

    是否有任何方法可以让curl告诉我它正在尝试哪些密码,服务器将接受哪些密码?

    使用wireshark,您可以看到客户端提供的密码。你也可以检查你的客户https://www.ssllabs.com/ssltest/viewMyClient.html显示提供了哪些密码。或者用openssl s_server -cipher ALL -www创建一个测试服务器,并将客户端连接到它,它将显示客户端和服务器共享的密码。

    我需要传递哪些选项给curl_setopt…

    值为ECDHE-ECDSA-AES128-SHA

    CURLOPT_SSL_CIPHER_LIST可能适用于您的情况。但是这个值实际上取决于你的curl是如何编译的。Curl支持不同的SSL/TLS后端,如OpenSSL, NSS, SecureTransport, channel, GnuTLS,确切的语法取决于后端。此示例设置对OpenSSL后端有效。

    如果我将密码设置为这个,会破坏其他网站吗?…

    如果您将自己全局限制为此集合,则yes。对于全局设置,您最好也添加其他设置,即HIGH:ECDHE-ECDSA-AES128-SHA:!aNULL。同样的错误,确切的语法取决于SSL/TLS后端。

    使用curl_setoptCURLOPT_SSL_CIPHER_LIST

    你只需要在PHP中添加curl选项

    curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'DEFAULT:!DH');
    

    on on on shell

    curl -I --ciphers 'DEFAULT:!DH' https://sslspdy.com
    

    相关内容

    • 没有找到相关文章

    最新更新