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

Posted

技术标签:

【中文标题】Curl:修复 CURL (51) SSL 错误:没有替代证书主题名称匹配【英文标题】:Curl: Fix CURL (51) SSL error: no alternative certificate subject name matches 【发布时间】:2014-01-17 12:59:15 【问题描述】:

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

尝试在http://www.evercam.io/docs/api/v1/authentication 访问 Rest API 以进行基本身份验证。

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

成功设置 CURL 后,不知道如何在 windows 命令提示符下使用此命令。测试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 错误?

【问题讨论】:

【参考方案1】:

api.evercam.io 的证书中的通用名称是 *.herokuapp.com,并且证书中没有替代主题名称。这意味着,api.evercam.io 的证书与主机名不匹配,因此证书验证失败。 与 www.evercam.io 相同,例如使用浏览器尝试https://www.evercam.io,您会收到错误消息,即证书中的名称与主机名不匹配。

所以这是需要evercam.io解决的问题。如果您不关心安全性、中间人攻击等,您可能会禁用证书验证 (curl --insecure),但是您应该问问自己为什么使用 https 而不是 http。

【讨论】:

【参考方案2】:

这通常发生在证书与主机名不匹配时。

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

更多可以在这里找到:http://curl.haxx.se/docs/sslcerts.html

【讨论】:

答案告诉关闭检查,还应该强调后果是什么。这很危险! 我认为证书上的主题名称是*.my-domain.com,不适用于dev.subdomain.my-domain.com。但适用于dev-subdomain.my-domain.com。因此,要使多个子域工作,也许您需要本文所说的 - sslshopper.com/…【参考方案3】:

编者注:这是一种非常危险的方法,如果您使用的 php 版本足够老就可以使用它。它使您的代码容易受到中间人攻击,并消除了加密连接的主要目的之一。这样做的能力已从现代版本的 PHP 中删除,因为它非常危险。这被赞成 70 次的唯一原因是人们很懒惰。不要这样做。


我知道这是一个(非常)古老的问题,而且是关于命令行的,但是当我在 Google 上搜索“SSL:没有替代证书主题名称与目标主机名匹配”时,这是第一次命中。

我花了很长时间才弄清楚答案,所以希望这可以节省很多时间! 在 PHP 中将此添加到您的 cUrl setopts:

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

ps:这应该是一个临时解决方案。由于这是一个证书错误,最好的办法是修复证书!

【讨论】:

好吧,这出现在我的谷歌搜索中,用于搜索我在 PHP 中遇到的问题,所以这对我很有帮助。 我做了同样的搜索,很高兴在这里得到你的答案。谢谢! CURLOPT_SSL_VERIFYHOST 在我的情况下就足够了 如果您还没有证书,感谢您用于测试目的。【参考方案4】:

正如错误代码所说,“没有替代证书主题名称与目标主机名匹配” - 因此 SSL 证书存在问题。

证书应包含 SAN,并且只会使用 SAN。一些浏览器会忽略已弃用的通用名称。

RFC 2818 明确指出 “如果存在 dNSName 类型的 subjectAltName 扩展,则必须 用作身份。否则,(最具体的)通用名称 必须使用证书的主题字段中的字段。虽然 通用名称的使用是现有的做法,它已被弃用并且 鼓励证书颁发机构改用 dNSName。"

【讨论】:

【参考方案5】:

我遇到了同样的问题。就我而言,我使用的是 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;

【讨论】:

你能解释一下为什么default_serverstatement 是个问题吗?您是否将其他配置标记为默认服务器?我在同一台主机上遇到了这个 curl 问题,而不是外部连接。【参考方案6】:

这可能会为某人节省一些时间。

如果您使用 GuzzleHttp 并遇到此错误消息 cURL 错误 60:SSL:没有替代证书主题名称与目标主机名匹配,您可以使用 '不安全的解决方案(不建议在生产中使用),那么您必须添加 \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 documentation

验证

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

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

【讨论】:

以上是关于Curl:修复 CURL (51) SSL 错误:没有替代证书主题名称匹配的主要内容,如果未能解决你的问题,请参考以下文章

如何修复 curl:(60)SSL 证书:证书链无效

CurlException: [curl] 51: SSL: 证书验证失败

解决curl中errno为51和60的错误

Paypal 沙箱 CURL 执行 - “SSL 连接错误”

https ( SSL ) 的 curl 命令

WORDPRESS : cURL 错误 60: SSL 证书