【问题标题】:PHP cURL certificate errorPHP cURL 证书错误
【发布时间】:2015-12-27 01:29:48
【问题描述】:

我正在尝试将自定义 cer-certificate 添加到我的 PHP cURL 请求中,但我不断收到此错误:

error setting certificate verify locations:
  CAfile: /path/to/my/cert.cer
  CApath: none

我对这个错误的发现是:

  1. 路径是相对的。
    如您所见,我提供了一个绝对路径。

  2. 路径错误。
    我试过var_dump(file_exists($certLocation));,它给了我true,所以不是这样。

  3. 文件的权限不正确。
    出于调试目的,我已将权限设置为 777。错误仍然存​​在。

  4. 文件路径在链中某处没有+x-权限。
    我也设置了这个,确保从 root 开始的整个路径都有+x-permissions,但仍然没有运气。

我在这里不知所措,已经尝试了我能找到的一切,而事实是,我什至不明白错误的真正含义。什么是verify location?我能理解的是加载文件时出错。

非常感谢任何对此的启发。请参阅下面的代码示例。

谢谢。

我使用的代码:

<?php

$oCurl = curl_init($this->baseUrl);
curl_setopt($oCurl, CURLOPT_FAILONERROR, 1);
curl_setopt($oCurl, CURLOPT_TIMEOUT, $this->timeout);
curl_setopt($oCurl, CURLOPT_CONNECTTIMEOUT, $this->connectionTimeout);
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($oCurl, CURLOPT_POST, 1);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($oCurl, CURLOPT_CAINFO, "/tmp/cert.cer");

错误:

error setting certificate verify locations:
  CAfile: /tmp/cert.cer
  CApath: none

【问题讨论】:

  • 您的 *.cer 文件有正确的用户和组集吗?和你的脚本一样,就是访问它?
  • 检查您的php.ini 上的curl.cainfo 值,如果您能够将其修改为curl.cainfo=/tmp/cert.cer
  • @HelgeTalvikSöderström 这是一个意外的输出。你的 /tmp/cert.cer 不是 PEM 格式的证书吗? file /tmp/cert.cer 的输出是什么?
  • @HelgeTalvikSöderström 哦,我想我明白你有什么样的文件;该命令现在应该可以正确读取:openssl x509 -in /tmp/cert.cer -inform der -text -noout,检查它是否是 CA 证书;我的猜测是您尝试使用的 cer 不是 CA 或 CA 捆绑包,或者如果是,那么它不是签署您尝试连接的 url 上使用的证书的 CA。
  • @HelgeTalvikSöderström 哦,我正忙着写答案,没有注意到你在这里评论:) 忽略我的最后一行答案,毕竟你有一个适当的 CA xD

标签: php curl certificate


【解决方案1】:

如果您的 PHP 安装没有最新的 CA 根证书捆绑包,请在 curl 网站上下载该捆绑包并将其保存在您的服务器上:

http://curl.haxx.se/docs/caextract.html

然后在您的php.ini 文件中为其设置path,例如在 Windows 上:

curl.cainfo=c:\php\cacert.pem

注意:
关闭 CURLOPT_SSL_VERIFYPEER 允许中间人 (MITM) 攻击,这是您不想要的!


SRC1 - https://stackoverflow.com/a/14064903/797495
SRC2 - http://php.net/manual/en/function.curl-setopt.php#110457

【讨论】:

    【解决方案2】:

    CURLOPT_CAINFOCURLOPT_SSL_VERIFYPEER结合使用

    CURLOPT_CAINFO 应设置为 PEM 格式的 CA 或 CA 捆绑包。我设法跟踪触发此错误的 curl 代码,这就是我发现的:

    curl/openssl.c:

    if(!SSL_CTX_load_verify_locations(connssl->ctx,
                                       data->set.str[STRING_SSL_CAFILE],
                                       data->set.str[STRING_SSL_CAPATH])) {
      if(data->set.ssl.verifypeer) {
        /* Fail if we insist on successfully verifying the server. */
        failf(data, "error setting certificate verify locations:\n"
              "  CAfile: %s\n  CApath: %s",
              data->set.str[STRING_SSL_CAFILE]?
              data->set.str[STRING_SSL_CAFILE]: "none",
              data->set.str[STRING_SSL_CAPATH]?
              data->set.str[STRING_SSL_CAPATH] : "none");
        return CURLE_SSL_CACERT_BADFILE;
      }
      ...
    

    显然对SSL_CTX_load_verify_locations 的调用返回0 并结合将CURLOPT_SSL_VERIFYPEER 设置为1 的事实触发了错误。

    SSL_CTX_load_verify_locations 是 openssl 库中的一个函数,根据文档 (SSL_CTX_load_verify_locations documentation),应考虑以下语句:

    "如果 CAfile 不为 NULL,则指向 PEM 格式的 CA 证书文件。"

    “CAfile 在 SSL_CTX_load_verify_locations() 函数执行时被处理。”

    “0 - 操作失败,因为 CAfile 和 CApath 为 NULL 或指定位置之一的处理失败。”在返回值部分


    您可以尝试使用以下命令将您的cer 转换为pem

    openssl x509 -in /tmp/cert.cer -inform der -outform pem -out /tmp/cert.pem
    

    但我不能保证这会起作用,因为我不确定您是否有正确的 CA 或 CA 捆绑文件。

    【讨论】:

    • 是的,问题是.cer-文件是der-格式。运行提供的命令将其从der 转换为pem 使一切正常。非常感谢您的时间和帮助!
    猜你喜欢
    • 2012-09-17
    • 2022-01-26
    • 2015-04-29
    • 1970-01-01
    • 2017-11-21
    • 2018-02-19
    • 2016-09-23
    • 2015-06-05
    • 2017-09-17
    相关资源
    最近更新 更多