使用 PEM 文件在 PHP 中推送通知

Posted

技术标签:

【中文标题】使用 PEM 文件在 PHP 中推送通知【英文标题】:Push Notification in PHP using PEM file 【发布时间】:2015-03-29 01:30:50 【问题描述】:

我一直在阅读 Ray Wenderlich 的关于使用 php 脚本的推送通知的教程。

参考:http://www.raywenderlich.com/32960/apple-push-notification-services-in-ios-6-tutorial-part-1

http://www.raywenderlich.com/32963/apple-push-notification-services-in-ios-6-tutorial-part-2

我进行了大量研究,但在第 2 部分中遇到了一个问题,您使用 ck.pem 文件运行 push.php 文件。

/Applications/XAMPP/bin/php push.php development

我唯一的区别是我使用的是 XAMPP 而不是 MAMP。

我已确认已安装所有扩展程序。

我可以通过这样做在终端中测试我的证书:

openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert PushChatCert.pem -key PushChatKey.pem

它要求我输入密码,我输入了。一切都在终端中成功运行。

但是,当我运行 push.php 文件时,出现以下错误:

PHP 警告:stream_socket_client():SSL 操作失败,代码为 1。OpenSSL 错误消息: 错误:14090086:SSL 例程:SSL3_GET_SERVER_CERTIFICATE:证书验证失败 PHP 警告:stream_socket_client(): 无法启用加密

PHP 警告:stream_socket_client():无法在第 140 行连接到 ssl://gateway.sandbox.push.apple.com:2195(未知错误)

php文件中的第140行是:

$this->fp = stream_socket_client('ssl://' . $this->server, $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);

我找到了这些:

iOS push notification does not work when using crontab scheduler

https://devforums.apple.com/message/1054840#1054840

Push notification in PHP

我确实重试了所有内容。我知道我的密码是正确的。我重新创建了我的证书、pem 文件和密钥。没有任何效果。每次我这样做时都会出现同样的错误。

我很困惑。

有没有人有任何建议或知道发生了什么?

谢谢!

更新 1:

我还尝试设置 ck.pem 文件的完整路径,但也无法修复错误。

【问题讨论】:

您确定您的 .p12 导出正确吗?从钥匙串导出私钥时,请确保您使用了私钥,而不仅仅是公钥 @Emilie 我只导出了私钥。我没有导出公钥,因为教程也没有告诉我。 $ctx的值是多少,上面设置了哪些选项? @oflannabhra 选项集:stream_context_set_option($ctx, 'ssl', 'local_cert', $this->certificate); stream_context_set_option($ctx, 'ssl', 'passphrase', $this->passphrase); $ctx 打印出 Resource id #9 当然,我不知道这是什么意思。 $this->certificate 应该是您本地证书的绝对文件路径。 【参考方案1】:

好吧,我终于想通了!经过2天的工作。

因此,对于遇到此问题的其他人:

从以下网址下载 entrust_2048_ca.cer 证书: https://www.entrust.com/get-support/ssl-certificate-support/root-certificate-downloads/

向下滚动并获取 Entrust.net 证书颁发机构 (2048)

然后,在 push.php 文件中,设置密码短语的上下文后,添加以下行: stream_context_set_option($ctx, 'ssl', 'cafile', 'entrust_2048_ca.cer');

【讨论】:

帮助很大! 答案中的 URL 现在已损坏。此时正确的是 entrust.com/get-support/ssl-certificate-support/… 并向下滚动到 Entrust.net Certificate Authority (2048) 我希望我能在 5 小时前找到您的帖子!我一直在尝试一切。我注意到如果我从脚本工作的 url 中删除了“ssl://”,但我从未在我的 iPhone 上收到推送通知。我遇到有人说要添加 stream_context_set_option($ctx, 'ssl', 'verify_peer', false);这会破坏服务器验证。作为一个故障排除的想法,我尝试了它,然后推送成功了。那时,我知道问题出在服务器验证上。早些时候,我已经下载了委托证书并将其添加到我的系统钥匙串中,但这并没有帮助。真是太感谢你了!!! 非常感谢!在 MacOS Sierra 中,这是解决方案! 如果可以的话,我会两次支持你的答案。我被困在这个问题上几天了,我开始把头发扯下来。非常感谢!【参考方案2】:

已更新至 macOS Sierra 10.12.4


问题出在 ma​​cOS Sierra 中的新 PHP 版本。 他们改变了使用证书的方式。

我建议对已接受的答案进行一些小改动,以使事情变得明确。

在创建流上下文时,您必须设置路径到entrust_2048_ca.cer 和其他参数,例如

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

The full explanation and links are here

【讨论】:

【参考方案3】:

更新到 macOS sierra 10.12.5

请补充

stream_context_set_option($ctx, 'ssl', 'verify_peer', false);

问题出在 macOS Sierra 的新 PHP 版本中

【讨论】:

【参考方案4】:

添加

stream_context_set_option($ctx, 'ssl', 'verify_peer', false);

这会导致服务器验证失败。 在上面的评论中感谢@百万分之一的应用程序。

【讨论】:

以上是关于使用 PEM 文件在 PHP 中推送通知的主要内容,如果未能解决你的问题,请参考以下文章

我们应该在服务器上使用哪个文件来推送通知,.pem 还是 .p12?

无法在 .NET 中向 iPhone 推送通知 - .PEM 证书问题?

为推送通知创建.pem 文件?

[使用.p8文件在php中发送iOS推送通知

服务器端 Apple 推送通知

服务器更改时推送通知不起作用