【问题标题】:cURL, php and SSL errorcURL、php 和 SSL 错误
【发布时间】:2018-07-12 02:58:39
【问题描述】:

我从一个组织那里得到了如何使用 CA、密钥和证书连接到他们的服务器的说明。在终端中成功尝试了以下内容:

openssl s_client -connect api-system3.xxxx.com:443 -CAfile teliasonerarootcav1.cer -cert BolagACert.crt -key BolagAKey.key

以及随后的 GET 请求。似乎恢复正常:

    CONNECTED(00000003)
    depth=2 O = TeliaSonera, CN = TeliaSonera Root CA v1
    verify return:1
    depth=1 C = FI, O = TeliaSonera, CN = TeliaSonera Server CA v2
    verify return:1
    depth=0 C = SE, L = XXXXX, O = XXXXX, OU = IT, CN = *.XXXX.COM
    verify return:1
    ---
    Certificate chain
     0 s:/C=SE/L=XXXXX/O=XXXXX/OU=IT/CN=*.XXXXXX
       i:/C=FI/O=TeliaSonera/CN=TeliaSonera Server CA v2
     1 s:/C=FI/O=TeliaSonera/CN=TeliaSonera Server CA v2
       i:/O=TeliaSonera/CN=TeliaSonera Root CA v1
    ---
    Server certificate
    -----BEGIN CERTIFICATE-----
   XXXXXX
    -----END CERTIFICATE-----
    subject=/C=XX/L=XXXXX/O=XXXXXX/OU=IT/CN=*.XXXXXX.COM
    issuer=/C=FI/O=TeliaSonera/CN=TeliaSonera Server CA v2
    ---
    No client certificate CA names sent
    Peer signing digest: SHA256
    Server Temp Key: ECDH, P-256, 256 bits
    ---
    SSL handshake has read 3879 bytes and written 441 bytes
    ---
    New, TLSv1/SSLv3, Cipher is XXXXX
    Server public key is 2048 bit
    Secure Renegotiation IS supported
    Compression: NONE
    Expansion: NONE
    No ALPN negotiated
    SSL-Session:
        Protocol  : TLSv1.2
        Cipher    : XXXXX
        Session-ID: XXXXXX
        Session-ID-ctx: 
        Master-Key: XXXXXX
        Key-Arg   : None
        PSK identity: None
        PSK identity hint: None
        SRP username: None
        Start Time: 1517505794
        Timeout   : 300 (sec)
        Verify return code: 0 (ok)
    ---
    GET /XXXXXX/
    depth=2 O = TeliaSonera, CN = TeliaSonera Root CA v1
    verify return:1
    depth=1 C = FI, O = TeliaSonera, CN = TeliaSonera Server CA v2
    verify return:1
    depth=0 C = XX, L = XXXX, O = XXXXX, OU = IT, CN = *.XXXXX.COM
    verify return:1
    read R BLOCK
    <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
    <html><head>
    <title>302 Found</title>
    </head><body>
    <h1>Found</h1>
    <p>The document has moved <a href="https://www.xxxxx.com/">here</a>.</p>
    <hr>
    <address>Apache Server at system3-jas123.system3.xxxxx.com Port 443</address>
    </body></html>
    read:errno=0

试图在 PHP cURL 请求中实现这一点,但下面的代码会产生错误:The requested URL returned error: 403 Forbidden

有什么想法吗?

代码:

$CAfile = getcwd()."/teliasonerarootcav1.cer";
$pemfile = getcwd()."/BolagACert.crt";
$keyfile = getcwd()."/BolagAKey.key";
$url = "https://xxxx.com/xxxxx";

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, $url); 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); 
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1); 
curl_setopt($ch, CURLOPT_FAILONERROR, 1); 
curl_setopt($ch, CURLOPT_SSLCERT, $pemfile); 
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.0.3705; .NET CLR 1.1.4322)');
curl_setopt($ch, CURLOPT_CAINFO,  $CAfile);
curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM'); 
curl_setopt($ch, CURLOPT_SSLKEY, $keyfile); 
$ret = curl_exec($ch);

//if error
if ($ret === false) {
    $info = curl_error($ch);
    curl_close($ch);
    die('Error: ' . $info);
}


curl_close($ch);

echo "<pre>";
print_r(json_decode($ret,true));
echo "</pre>";

【问题讨论】:

  • 这可能是该网站试图阻止非浏览器。参见例如PHP Curl gets 403 error, but browser from same machine can request page?。另一件事是,您的 openssl s_client 命令可能不会访问与 curl 相同的端点,以防服务器在使用不同的主机名访问时表现不同 - 使用 -servername 选项对此进行测试。
  • 在终端尝试了 -servername xxxx.com 但得到了完全相同的响应
  • 当您编辑$url = "https://xxxx.com/xxxxx"; 等重要信息时,我们无法帮助解决问题。由于 Stack Overflow 向您隐藏了关闭原因:寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定问题或错误以及在问题本身。没有明确问题陈述的问题对其他读者没有用处。请参阅:How to create a Minimal, Complete, and Verifiable example

标签: php ssl curl php-openssl


【解决方案1】:

SSL 和 HTTP 响应代码是两个不同的故事。首先您使用 SSL 连接到服务器,然后服务器处理请求并返回响应代码。在您的 openssl 转储中,没有任何关于 HTTP 响应代码的信息,因此它实际上可能返回了 403。另一方面,PHP 中的 403 响应意味着您已正确设置连接并且服务器确实处理了您的请求。请检查 API 是否需要传递某种凭据。

【讨论】:

  • 403 Forbidden 返回,这到底是什么意思?
  • 这意味着服务器希望您的脚本“登录”,即提供某种方式来标识自己(如 API 密钥、合作伙伴 ID、用户和密码或身份验证令牌,或者我不知道什么)并证明它有足够的权限来执行请求。有关详细信息,请参阅 API 的文档或其支持团队。
猜你喜欢
  • 2012-09-17
  • 2013-02-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-22
  • 2010-11-19
  • 1970-01-01
相关资源
最近更新 更多