MAMP和PHP“ SSL操作失败,代码1”

时间:2019-01-03 17:34:01

标签: php openssl ssl-certificate mamp self-signed

编辑 我目前正在忙碌中,并且iPhone上的Stack Exchange应用程序上只有SO,所以下面的代码中的引号有些奇怪-抱歉!我的真实代码中有真实的代码:)

我一直在努力解决这一问题,还有关于SO的其他一些问题,但是这里...

只需尝试使用file_get_contents()来捕获位于同一服务器和同一域上的另一个文件的网页,并将其包括在内。我正在使用带有自签名证书的MAMP进行生产(这样我就可以使服务器强制使用SSL等),而且我还在Mac本地将该证书设置为“始终受信任”,因为它显然是自签名的。

因此,现在出现了一个问题,我希望一个页面捕获另一页面的内容。.我最初尝试使用cURL,但是在没有给我任何异常的情况下失败了,并且使用curl_error()也没有信息,所以我切换了到file_get_contents(),在那里我得到异常SSL operation failed with code 1 ... ssl3_get_server_certificate:certificate verify failed

我认为这是由于OpenSSL不信任自签名而引起的(但是我认为它使用了底层OS的受信任CA?),并且我无法使用以下流上下文来使它起作用:

stream_context_create([
   "ssl" => [
      "allow_self_signed" => true
   ]
]);

如果我将verify_peerverify_peer_name设置为false,则会发出请求,但不会发送HTTPS cookie,这会破坏整个过程。

我尝试将证书的实际文本添加到MAMP的OpenSSL目录下的cacert.pem文件中,并将该文件在openssl.cafile文件的php.ini选项中设置为在另一个答案中指出,但可惜没有运气...

有什么想法吗?您的帮助将不胜感激!谢谢! ☺️

编辑2 所以我再次使用cURL尝试了一次,这次得到了cURL给我一些详细的输出到文件,这就是它给我的结果(请注意,从底部开始的第三行):

*   Trying ::1...
* TCP_NODELAY set
* Connected to admin.voyagerisc (::1) port 8890 (#0)
* ALPN, offering http/1.1
* Cipher selection: ALL:!EXPORT:!EXPORT40:!EXPORT56:!aNULL:!LOW:!RC4:@STRENGTH
* successfully set certificate verify locations:
*   CAfile: /Applications/MAMP/Library/OpenSSL/certs/cacert.pem   CApath: none
* SSL certificate problem: unable to get local issuer certificate
* Curl_http_done: called premature == 1
* Closing connection 0

...这是我将原始证书添加到顶部的文件。

2 个答案:

答案 0 :(得分:0)

TLDR;您需要成为自己的(微型)CA,以便拥有可以信任的根证书

因此,经过几天的艰苦努力,我终于弄清楚了这一点,希望下面对毫无疑问会遇到此问题的MAMP / PHP用户有所帮助!

基本上,file_get_contents()cURL在OpenSSL之上运行,(据我所知,我是一个SSL noob!)OpenSSL,就像每个设备基本上都列出了所有主要证书颁发机构的清单一样根证书。因此,在OpenSSL的眼中,如果其中任何一个证书已被其中一个根证书签名,则可以信任。

现在,您可以进入OpenSSL使用的具有所有大根证书的文件,我认为这就像将开发站点的原始自签名证书放在列表顶部一样容易,并且一切都会掉到位。 但是,由于某种原因,如果它不是 ROOT CERTIFICATE ,则OpenSSL将不信任它。

长话短说,这是步骤:

  1. 跟随this guide,在不到5分钟的时间内成为您自己的CA。 (作为旁注,现在这意味着您可以信任 just 新创建的根证书,对于您想要使用SSL的每个开发站点,都可以使用该根证书进行自签名,而您不需要重新信任等)
  2. 一旦您根据文章信任了根证书,并pointed MAMP信任了特定站点的密钥和证书,则在IDE中打开.pem文件。您创建的 ROOT CERTIFICATE ,而不是您的开发站点专用的
  3. 对于MAMP,文件OpenSSL用作受信任证书颁发机构的核心列表,位于/Applications/MAMP/Library/OpenSSL中-在IDE中也打开cacert.pem
  4. 现在,在注释下和第一个真实CA之前,复制并粘贴您的“根证书”的原始数据。您还可以在较长的数据之前(以及之前 -----BEGIN CERTIFICATE-----行)添加您在第一步中为证书颁发机构设置的名称,并使用{{1 }}与其他证书颁发机构一样。
  5. 通常:保存并重新启动MAMP

现在,如果您正在运行具有MAMP的本地开发服务器并启用了自签名SSL,那么您现在应该能够对服务器本身进行SSL调用,并获得服务器的信任。 ?我猜?当你想起来的时候很奇怪!

最后一点,如果您曾经在SO上访问过其他类似问题,则会看到许多答案提示您使用=创建一个流上下文,或者使用{{1 }}资源,建议在流上下文中切换get_file_contents()cURL"verify_peer" => false的等效选项。我压力不足,因为您可能会忘记重新打开SSL或其他一些令人不快的事件,这种方法完全无法达到SSL的目的,甚至不应该用于本地开发相信不参与生产。

我上面描述的方法比较繁琐,是的,但是它将引导您进行开发,直到您在生产中拥有由真正的CA签署的真实SSL证书为止,这时这不再是问题。 / p>

如果此解释不够清楚/不够精确,请随时发表评论,我只是想办法而已!干杯:)

答案 1 :(得分:0)

正如 Mike 提到的(见评论),在当前版本的 MAMP (6.4) 中有一个无效的证书文件添加到 /Applications/MAMP/Library/OpenSSL/certs/cacert.pem。只需打开此文件并访问 301 重定向 (https://curl.se/ca/cacert.pem) 中显示的链接,下载并替换文件。