简体   繁体   English

带有自签名证书的 POST 请求

[英]POST request with a self-signed certificate

I'm going to POST some data from site A to site B using PHP.我将使用 PHP 将一些数据从站点 A 发布到站点 B。 Site A has a commercial SSL certificate.站点 A 具有商业 SSL 证书。 Site B is going to have a self-signed certificate.站点 B 将拥有自签名证书。 Is this doable?这是可行的吗? If not, are there any configuration options in PHP (or Apache) that I can set to bypass the restrictions?如果没有,我可以设置 PHP(或 Apache)中的任何配置选项来绕过这些限制吗?

Presumably you'll be using curl on server A?想必您会在服务器 A 上使用 curl 吗? There's a couple options in curl to disable certificate validation, which'll allow self-signed certs through. curl 中有几个选项可以禁用证书验证,这将允许自签名证书通过。 The link will still be encrypted, but you won't be able to trust that server B really IS server B:该链接仍将被加密,但您将无法相信服务器 B 真的服务器 B:

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

Example PHP code:示例 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);

Answers suggesting to disable CURLOPT_SSL_VERIFYPEER should not be accepted.不应接受建议禁用CURLOPT_SSL_VERIFYPEER答案。 The question is "Why doesn't it work with cURL", and as correctly pointed out it is dangerous.问题是“为什么它不适用于 cURL”,正如正确指出的那样,它很危险。 Disabling certificate checks opens the door for man in the middle attacks, which comes close to using just plain text http.禁用证书检查为中间人攻击打开了大门,这接近于仅使用纯文本 http。

The error is probably caused by not having an up-to-date bundle of CA root certificates.该错误可能是由于没有最新的 CA 根证书包引起的。 This is typically a text file with a bunch of cryptographic signatures that curl uses to verify a host's SSL certificate.这通常是一个带有一堆加密签名的文本文件,curl 使用这些签名来验证主机的 SSL 证书。

You need to make sure that your installation of PHP has one of these files, and that it's up to date (otherwise download one here: http://curl.haxx.se/docs/caextract.html ).您需要确保您的 PHP 安装具有这些文件之一,并且它是最新的(否则请在此处下载: http : //curl.haxx.se/docs/caextract.html )。

Then set in php.ini:然后在php.ini中设置:

curl.cainfo = <absolute_path_to> cacert.pem

If you are setting it at runtime, use:如果您在运行时设置它,请使用:

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

Answer copied from https://stackoverflow.com/a/23585500/2650835 for security reasons.出于安全原因,从https://stackoverflow.com/a/23585500/2650835复制的答案。

It's doable.这是可行的。 In PHP, if you are using cURL to perform the POST, you just need to set the options CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST to false so it doesn't fail because the certificate is self signed.在 PHP 中,如果您使用 cURL 执行 POST,您只需将选项CURLOPT_SSL_VERIFYPEERCURLOPT_SSL_VERIFYHOST为 false,这样它就不会因为证书是自签名而失败。

If you are asking the browser to POST the data, then the user will get the normal warnings about the certificate not being trusted.如果您要求浏览器 POST 数据,那么用户将收到有关证书不受信任的正常警告。

If you're using cURL to perform the POST from within your PHP code, you'll want to disable cURL's SSL checks.如果您使用 cURL 从 PHP 代码中执行 POST,您需要禁用 cURL 的 SSL 检查。 According to a related question ,根据一个相关的问题

You'll need to set CURLOPT_SSL_VERIFYPEER and CURLOPT_SSL_VERIFYHOST to FALSE .您需要将CURLOPT_SSL_VERIFYPEERCURLOPT_SSL_VERIFYHOSTFALSE This should disable the two main checks.这应该禁用两个主要检查。 They may not both be required, but this should at least get you going.它们可能不是必需的,但这至少应该让你前进。

You can post to websites with self-signed certificates by adding the website's certificates to your list of trusted CAs.您可以通过将网站的证书添加到您的受信任 CA 列表来发布具有自签名证书的网站。 I've tested this in Debian, perhaps it also works in Ubuntu, CentOS, etc.我已经在 Debian 中测试过了,也许它也适用于 Ubuntu、CentOS 等。

First get the self-signed website's certificate (ssws = self signed website):首先获取自签名网站的证书(ssws = 自签名网站):

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

Ctrl-C out of the openssl command and examine the output. Ctrl-C 退出 openssl 命令并检查输出。 Locate the server's self-signed certificate which is encoded between these markers:找到在这些标记之间编码的服务器的自签名证书:

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

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

Copy the certificate, markers and all, and paste its contents into a new file, and give the file a ".crt" extension, such as "my-favorite-self-signed-website.crt".复制证书、标记和所有内容,并将其内容粘贴到一个新文件中,并为该文件指定一个“.crt”扩展名,例如“my-favorite-self-signed-website.crt”。 Then...然后...

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

The last command should indicate "1 added", indicating your self signed website is now a bona fide trusted entity to this computer. 最后一个命令应指示“1 添加”,表明您的自签名网站现在是这台计算机的真正可信实体。 PHP will automatically pick this up from the system and fall in line. PHP 会自动从系统中选择它并符合要求。

Unless you are doing some very preliminary development/testing/integration YOU SHOULD NEVER DISABLE PEER VERIFICATION IN SSL/TLS, as has been offered in other answers.除非您正在进行一些非常初步的开发/测试/集成,否则您永远不应禁用 SSL/TLS 中的对等验证,正如其他答案中所提供的那样。 Without peer verification, you might as well just do plain HTTP.如果没有对等验证,您不妨只做普通的 HTTP。

In my case, only my development server is self-signed, so I set the verifypeer option to false and it works.就我而言,只有我的开发服务器是自签名的,所以我将 verifypeer 选项设置为 false 并且它可以工作。 But my production server is fully signed, so I do not set the verifypeer option.但是我的生产服务器是完全签名的,所以我没有设置 verifypeer 选项。 In either case, the verifyhost option is unnecessary.无论哪种情况,都不需要 verifyhost 选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM