Curl:修复CURL(51)SSL错误:没有匹配的备用证书主题名称

124

我是CURL世界的新手,来自Windows + .NET领域。

尝试访问基本认证的Rest API,位于http://www.evercam.io/docs/api/v1/authentication

curl -X GET https://api.evercam.io/v1/... \
-u {username}

在 Windows 命令提示符中,已经成功安装 CURL,但不知道如何使用该命令。以下是测试 CURL 的方法:

C:\>curl --version
curl 7.33.0 (x86_64-pc-win32) libcurl/7.33.0 OpenSSL/0.9.8y zlib/1.2.8 libssh2/1.4.3
Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp scp s
ftp smtp smtps telnet tftp
Features: AsynchDNS GSS-Negotiate Largefile NTLM SSL SSPI libz

现在我要以这个结束

C:\>curl -u myuser:mypassword -X GET https://api.evercam.io/v1/
curl: (51) SSL: no alternative certificate subject name matches target host name 'api.evercam.io'

我该如何修复SSL错误51问题?

7个回答

154

通常发生这种情况是因为证书与主机名不匹配。

解决方法是联系主机,要求其修复其证书。
否则,您可以关闭cURL对证书的验证,使用-k(或--insecure)选项。
请注意,正如选项所述,它是不安全的。您不应该使用此选项,因为它可能导致中间人攻击,并破坏HTTPS的目的。

更多信息请参见:http://curl.haxx.se/docs/sslcerts.html


17
提供让你关闭支票功能的答案,也应该强调其后果。这是危险的! - DrP3pp3r
3
我理解的是证书上的主题名称是 *.my-domain.com,但对于 dev.subdomain.my-domain.com 不适用。但对于 dev-subdomain.my-domain.com 却可以正常使用。因此,如果要使多个子域名工作,也许需要按照这篇文章所说的去做 - https://www.sslshopper.com/article-ssl-certificates-for-multi-level-subdomains.html。 - prayagupa
1
@prayagupa 你应该把你的回答设为最佳答案。被接受的答案是给那些还不理解事情端到端影响的经验不足的开发人员的。 - eco

94

编辑注:如果您使用的是足够旧的PHP版本,则这是一种非常危险的方法。它会使您的代码暴露于中间人攻击,并删除加密连接的主要目的之一。现代版本的PHP已将此功能移除,因为它非常危险。唯一被点赞70次的原因是因为人们懒惰。请不要这样做。


我知道这是一个(非常)古老的问题,而且与命令行有关,但当我在Google上搜索“SSL:no alternative certificate subject name matches target host name”时,这是第一个搜索结果。

我花了很长时间才弄明白答案,所以希望这篇文章能节省其他人很多时间!在PHP中,将以下内容添加到您的cUrl setopts中:

curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);

p.s:这应该只是一个临时解决方案。由于这是证书错误,最好的方法当然是修复证书!


33
这在我搜索PHP问题时出现在谷歌搜索结果中,对我很有帮助。 - Kudit
1
我进行了相同的搜索,很高兴在这里得到了你的答案。谢谢! - CptMisery
2
在我的情况下,CURLOPT_SSL_VERIFYHOST 就足够了。 - 1234ru
1
谢谢,这对于测试目的非常有用,如果您还没有准备好证书。 - Andrew

22
证书中的通用名称为 api.evercam.io,但实际上证书是针对 *.herokuapp.com,且证书中没有备用主题名称。这意味着,api.evercam.io 的证书与主机名不匹配,因此证书验证失败。同样的情况也适用于 www.evercam.io,例如在浏览器中尝试访问 https://www.evercam.io 时会出现错误消息,提示证书名称与主机名不匹配。
因此,这是一个需要 evercam.io 解决的问题。如果您不关心安全、中间人攻击等问题,可以禁用证书验证(curl --insecure),但那么您应该问问自己为什么使用 https 而不是 http。

6

希望能对某些人节省时间。

如果您使用GuzzleHttp,并且遇到此错误消息cURL error 60: SSL: no alternative certificate subject name matches target host name,并且您接受“不安全”的解决方案(不建议在生产环境中使用),则需要将\GuzzleHttp\RequestOptions::VERIFY => false添加到客户端配置中:

$this->client = new \GuzzleHttp\Client([
    'base_uri'                          => 'someAccessPoint',
    \GuzzleHttp\RequestOptions::HEADERS => [
        'User-Agent' => 'some-special-agent',
    ],
    'defaults'                          => [
        \GuzzleHttp\RequestOptions::CONNECT_TIMEOUT => 5,
        \GuzzleHttp\RequestOptions::ALLOW_REDIRECTS => true,
    ],
    \GuzzleHttp\RequestOptions::VERIFY  => false,
]);

CurlFactory::applyHandlerOptions()方法中,将CURLOPT_SSL_VERIFYHOST设置为0并将CURLOPT_SSL_VERIFYPEER设置为false。

$conf[CURLOPT_SSL_VERIFYHOST] = 0;
$conf[CURLOPT_SSL_VERIFYPEER] = false;

来自 GuzzleHttp文档

verify

描述请求的SSL证书验证行为。

  • 设置为true以启用SSL证书验证并使用操作系统提供的默认CA捆绑包。
  • 设置为false以禁用证书验证(这是不安全的!)。
  • 设置为字符串以提供CA捆绑包的路径,以使用自定义证书进行验证。

2
我遇到了同样的问题。在我的情况下,我使用的是DigitalOcean和Nginx。
首先,我在DigitalOcean上设置了一个域名example.app和一个子域名dev.exemple.app。 其次,我从Godaddy购买了两个SSL证书。 最后,我在nginx中配置了两个域名,使用以下代码片段来使用这两个SSL证书。

我的example.app域名配置

    server {
    listen 7000 default_server;
    listen [::]:7000 default_server;

     listen 443 ssl default_server;
     listen [::]:443 ssl default_server;

    root /srv/nodejs/echantillonnage1;

    # Add index.php to the list if you are using PHP
    index index.html index.htm index.nginx-debian.html;

    server_name echantillonnage.app;
    ssl_certificate /srv/nodejs/certificatSsl/widcardcertificate/echantillonnage.app.chained.crt;
    ssl_certificate_key /srv/nodejs/certificatSsl/widcardcertificate/echantillonnage.app.key;

    location / {
            # First attempt to serve request as file, then
            # as directory, then fall back to displaying a 404.
            proxy_pass http://127.0.0.1:8090;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
    #try_files $uri $uri/ =404;
    }
 }

我的dev.example.app

   server {
    listen 7000 default_server;
    listen [::]:7000 default_server;

     listen 444 ssl default_server;
     listen [::]:444 ssl default_server;

    root /srv/nodejs/echantillonnage1;

    # Add index.php to the list if you are using PHP
    index index.html index.htm index.nginx-debian.html;

    server_name dev.echantillonnage.app;
    ssl_certificate /srv/nodejs/certificatSsl/dev/dev.echantillonnage.app.chained.crt;
    ssl_certificate_key /srv/nodejs/certificatSsl/dev/dev.echantillonnage.app.key;

    location / {
            # First attempt to serve request as file, then
            # as directory, then fall back to displaying a 404.
            proxy_pass http://127.0.0.1:8091;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
    #try_files $uri $uri/ =404;
    }
 }

当我在启动https://dev.echantillonnage.app时,我遇到了问题。
    Fix CURL (51) SSL error: no alternative certificate subject name matches

我的错误在下面两行:
    listen 444 ssl default_server;
     listen [::]:444 ssl default_server;

我必须将这个更改为:


     listen 443 ssl;
     listen [::]:443 ssl;

1
你能解释一下为什么这里的 default_server 声明会有问题吗? 你是否有其他标记为默认服务器的配置? 我在同一台主机上遇到了这个 curl 问题,而在外部连接中没有。 - Benibr

0
如错误代码所述:“没有备选证书主题名称与目标主机名匹配”-因此SSL证书存在问题。
证书应包含SAN,只有SAN将被使用。一些浏览器会忽略弃用的通用名称。
RFC 2818清楚地规定:“如果存在类型为dNSName的subjectAltName扩展名,则必须将其用作标识。否则,必须使用证书主题字段中(最具体的)通用名称字段。尽管使用通用名称是现有的实践方法,但它已经过时,并且鼓励认证机构使用dNSName。”

0

我做了类似的事情,但是为了测试的目的,我将主域名添加到了我的/etc/hosts文件中,并一直在努力解决它。所以请确保您也检查了那个文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接