带有自签名证书的POST请求

时间:2012-12-03 19:21:52

标签: php security post ssl ssl-certificate

我将使用PHP将一些数据从站点A发布到站点B.站点A具有商业SSL证书。站点B将拥有自签名证书。这可行吗?如果没有,PHP(或Apache)中是否有任何配置选项可以设置为绕过限制?

6 个答案:

答案 0 :(得分:22)

据推测,你将在服务器A上使用curl? curl中有几个选项可以禁用证书验证,这将允许通过自签名证书。该链接仍将加密,但您无法信任该服务器B真的 IS 服务器B:

curlopt_ssl_verifypeer  (checking the CA auth chain)
curlopt_ssl_verifyhost  (hostname/certname match checks)

示例PHP代码:

$ch = curl_init("https://example.com/example/path"); 
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$response = curl_exec($ch);

答案 1 :(得分:2)

这是可行的。在PHP中,如果您使用cURL执行POST,则只需将选项CURLOPT_SSL_VERIFYPEERCURLOPT_SSL_VERIFYHOST设置为false,这样就不会失败,因为证书是自签名的。

答案 2 :(得分:2)

如果您要求浏览器发布数据,那么用户将收到有关证书不受信任的正常警告。

如果您正在使用cURL从PHP代码中执行POST,则需要禁用cURL的SSL检查。根据{{​​3}},

  

您需要将CURLOPT_SSL_VERIFYPEERCURLOPT_SSL_VERIFYHOST设置为FALSE。这应该>禁用两个主要检查。它们可能不是必需的,但至少应该让你去。

答案 3 :(得分:1)

您可以通过将网站的证书添加到您的受信任 CA 列表来发布具有自签名证书的网站。我已经在 Debian 中测试过了,也许它也适用于 Ubuntu、CentOS 等。

首先获取自签名网站的证书(ssws = 自签名网站):

openssl s_client -connect <ssws-hostname>:<ssws-port>

Ctrl-C 退出 openssl 命令并检查输出。找到在这些标记之间编码的服务器自签名证书:

-----BEGIN CERTIFICATE-----

-----END CERTIFICATE-----

复制证书、标记和所有内容,并将其内容粘贴到一个新文件中,并为该文件指定一个“.crt”扩展名,例如“my-favorite-self-signed-website.crt”。然后……

sudo chmod 644 my-favorite-self-signed-website.crt
sudo chown root:root my-favorite-self-signed-website.crt
sudo mv my-favorite-self-signed-website.crt /usr/local/share/ca-certificates/.
sudo /usr/sbin/update-ca-certificates

last command 应表示“已添加 1 个”,表明您的自签名网站现在是该计算机的真正可信实体。 PHP 会自动从系统中提取并排入队列。

除非您正在进行一些非常初步的开发/测试/集成,否则您永远不应禁用 SSL/TLS 中的对等验证,正如其他答案中提供的那样。如果没有对等验证,您不妨只做普通的 HTTP。

答案 4 :(得分:0)

在我的情况下,只有我的开发服务器是自签名的,因此我将verifypeer选项设置为false并可以工作。但是我的生产服务器已完全签名,因此我没有设置verifypeer选项。无论哪种情况,都不需要verifyhost选项。

答案 5 :(得分:0)

建议禁用CURLOPT_SSL_VERIFYPEER的答案不应被接受。问题是“为什么它不适用于cURL”,并且如正确指出的那样,这很危险。禁用证书检查会为中级攻击打开大门,这几乎只使用纯文本http。

该错误可能是由于没有最新的CA根证书捆绑包引起的。这通常是带有一堆密码签名的文本文件,curl使用这些签名来验证主机的SSL证书。

您需要确保您的PHP安装中包含以下文件之一,并且文件是最新的(否则,请在此处下载文件:http://curl.haxx.se/docs/caextract.html)。

然后在php.ini中设置:

curl.cainfo = <absolute_path_to> cacert.pem

如果要在运行时进行设置,请使用:

curl_setopt ($ch, CURLOPT_CAINFO, dirname(__FILE__)."/cacert.pem");

出于安全原因从https://stackoverflow.com/a/23585500/2650835复制的答案。