我将使用PHP将一些数据从站点A发布到站点B.站点A具有商业SSL证书。站点B将拥有自签名证书。这可行吗?如果没有,PHP(或Apache)中是否有任何配置选项可以设置为绕过限制?
答案 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_VERIFYPEER
和CURLOPT_SSL_VERIFYHOST
设置为false,这样就不会失败,因为证书是自签名的。
答案 2 :(得分:2)
如果您要求浏览器发布数据,那么用户将收到有关证书不受信任的正常警告。
如果您正在使用cURL从PHP代码中执行POST,则需要禁用cURL的SSL检查。根据{{3}},
您需要将
CURLOPT_SSL_VERIFYPEER
和CURLOPT_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复制的答案。