返回

SSL_VERIFY_RESULT 为 0 的原因:HTTPS 证书验证疑难解答

php

HTTPS 证书验证疑难解答:SSL_VERIFY_RESULT 为 0 背后的原因

作为一名经验丰富的程序员,我在使用 cURL 时遇到过一个奇怪的问题:在尝试通过 HTTPS 访问网站时,即使没有可用的 HTTPS 版本,SSL_VERIFY_RESULT 也会返回 0(表示操作成功)。

问题

当使用 cURL 通过 HTTP 访问网站时,一切正常,返回 HTTP 代码 200。但是,当我尝试使用 HTTPS 版本访问时,虽然返回代码正确为 0(表示没有 HTTPS 版本),但 SSL_VERIFY_RESULT 却为 0,即“操作成功”。这让我感到困惑,因为没有证书可以验证。

原因探究

经过仔细研究,我发现 cURL 在处理 HTTPS 请求时会执行以下步骤:

  1. 检查服务器返回的证书: 即使没有可用的 HTTPS 版本,cURL 仍会检查服务器返回的证书。
  2. 确定证书是否过期: 如果服务器返回了证书,cURL 会检查其有效期并确定它是否过期。
  3. 验证证书的颁发者: 如果证书未过期,cURL 会检查颁发该证书的证书颁发机构(CA)是否受信任。
  4. 验证域名匹配: 最后,cURL 会验证证书中的域名是否与所请求的域名相匹配。

在本例中,由于没有可用的 HTTPS 版本,服务器不会返回证书,因此 cURL 无法执行步骤 1。因此,步骤 2、3 和 4 也就没有执行。

解决方案

要解决此问题,需要在 cURL 请求中禁用证书验证。这可以通过设置 CURLOPT_SSL_VERIFYHOSTCURLOPT_SSL_VERIFYPEER 选项为 0 来实现。

以下示例代码展示了如何禁用证书验证:

curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);

禁用证书验证后,cURL 将不再尝试验证证书,并且 SSL_VERIFY_RESULT 将始终为 0,无论 HTTPS 版本是否可用。

结论

经过一番探究,我发现了 SSL_VERIFY_RESULT 为 0 背后的原因。这是由于 cURL 无法执行证书验证,因为服务器没有返回证书。通过禁用证书验证,我解决了这个问题,并确保 cURL 能够正常访问 HTTP 站点。

常见问题解答

  1. 禁用证书验证会带来什么安全风险?

禁用证书验证可能会使你的应用程序容易受到中间人攻击,因为攻击者可以拦截你的请求并提供虚假证书。因此,只在必要时才禁用证书验证,并采取其他安全措施来保护你的应用程序。

  1. 除了禁用证书验证外,还有什么方法可以解决此问题?

另一个解决方案是使用自签名证书。自签名证书是颁发给自己的证书,不被任何受信任的 CA 认可。但是,你可以手动信任自签名证书,并继续使用 cURL 进行 HTTPS 请求。

  1. 为什么即使没有可用的 HTTPS 版本,cURL 仍会检查服务器返回的证书?

cURL 的行为是在某种程度上是多余的,但它可以防止服务器在以后提供 HTTPS 版本时发生意外问题。

  1. 我应该始终禁用证书验证吗?

不,你应该只在必要时才禁用证书验证。在大多数情况下,应该启用证书验证以确保应用程序的安全。

  1. 如果服务器返回了无效的证书,SSL_VERIFY_RESULT 会返回什么?

如果服务器返回了无效的证书,SSL_VERIFY_RESULT 会返回一个负值,表示验证失败。