APN使用macOS Sierra推送通知

我正尝试使用连接到ssl://gateway.push.apple.com:2195的简单PHP工具来发送手机的推送通知,但连接失败,并显示以下错误:

 Warning: stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in <Users/.../file.php> on line 30 Warning: stream_socket_client(): Failed to enable crypto in <Users/.../file.php> on line 30 Warning: stream_socket_client(): unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Unknown error) in <Users/.../file.php> on line 30 Failed to connect: 0 

这一切都是从我升级到macOS Sierra的转基因种子开始的。 macOS Sierra中有哪些新特性会影响SSL连接? 我如何解决这个问题?

我得到了同样的错误,这就是我所做的:

1)更新我的openssl (我认为你不需要这个)步骤2,因为这将需要约10分钟

 brew install openssl 

确保你更新了正确的:

 openssl version 

如果没有,请尝试这个或谷歌:

 brew link --force openssl 

2)检查你的php default_cert_filepath:

 php -r "print_r(openssl_get_cert_locations());" 

这是我得到的:

 Array ( [default_cert_file] => /usr/local/libressl/etc/ssl/cert.pem [default_cert_file_env] => SSL_CERT_FILE [default_cert_dir] => /usr/local/libressl/etc/ssl/certs [default_cert_dir_env] => SSL_CERT_DIR [default_private_dir] => /usr/local/libressl/etc/ssl/private [default_default_cert_area] => /usr/local/libressl/etc/ssl [ini_cafile] => [ini_capath] => ) 

3)从这里下载cacert.pem:

 wget http://curl.haxx.se/ca/cacert.pem 

4)将cacert.pem文件移到你的default_cert_filepath(作为root):

 sudo mv cacert.pem /usr/local/libressl/etc/ssl/cert.pem 

可能我需要先创build这个目录

在此之后,我的PHP脚本工作。

升级到macOS Sierra后,使用php脚本发送推送通知时出现同样的错误。

解决scheme与安装证书

[default_cert_file] => /usr/local/libressl/etc/ssl/cert.pem也没有帮助。


更新到PHP v。5.6.27,macOS Sierra 10.12.4


毕竟,我发现我的问题。 事实上, macOS Sierra更新了PHP版本到5.6.27

要检查它,inputterminal

php -v

 PHP 5.6.27 (cli) (built: Oct 23 2016 11:47:58) Copyright (c) 1997-2016 The PHP Group Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies 

这里是PHP 5.6.x中的OpenSSL更改

作为简短的解决方法,有人build议在php脚本中禁用全新的安全function(在上面的链接中,非常底部)。

更安全(我推荐它)将是一种设置pathentrust_2048_ca.cer显式的方式

  $streamContext = stream_context_create([ 'ssl' => [ 'verify_peer' => true, 'verify_peer_name' => true, 'cafile' => '/path/to/bundle/entrust_2048_ca.cer', ] ]); 

它也可以工作。

你可以从Entrust获得证书。 从https://www.entrust.com/get-support/ssl-certificate-support/root-certificate-downloads/下载entrust_2048_ca.cer证书&#x3002; 下载完entrust_2048_ca.cer之后 ,我把它复制到我的php脚本所在的目录下,并且一切正常。

更多细节在这里: https : //stackoverflow.com/a/28222783/4253579

添加@Sandar给出的答案,你也可以像这样设置cafile

 stream_context_set_option($streamContext, 'ssl', 'cafile', '/path/to/entrust_2048_ca.cer');