1

我正在尝试建立与 Apple 的 APNS 服务的连接。我在 Ubuntu 上运行 Mono。用于建立连接的代码可以在 Windows 环境中正常工作。该代码是 NT 服务(系统进程)的一部分,而不是网站或服务。

以下是有关环境的一些信息:Ubuntu 12.10。单声道 3.0.5。使用 Mono 的 Certmgr:

  • 我在 Mono 机器证书存储 (MY) 中安装了 APNS 证书。
  • 我在 Mono 机器证书存储(密钥对)中安装了 APNS 证书私钥。
  • 我在 Mono 机器证书存储区 (TRUST) 中安装了 Entrust.net 证书颁发机构 (2048) 根证书。
  • 我在 Mono 机器证书存储 (CA) 中安装了 Entrust 证书颁发机构 - 1LC 中间证书。

Telnet 能够到达 gateway.push.apple.com:2195。我正在调试 MonoDevelop 中的代码。MonoDevelop 以 Root (gksudo) 身份运行。

这是我收到的错误:

System.IO.IOException: The authentication or decryption has failed. --->
Mono.Security.Protocol.Tls.TlsException: The authentication or decryption has failed.
at Mono.Security.Protocol.Tls.RecordProtocol.ProcessAlert (AlertLevel alertLevel, AlertDescription alertDesc) [0x00000] in <filename unknown>:0
at Mono.Security.Protocol.Tls.RecordProtocol.InternalReceiveRecordCallback (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0
--- End of inner exception stack trace ---
at Mono.Security.Protocol.Tls.SslStreamBase.AsyncHandshakeCallback (IAsyncResult asyncResult) [0x00000] in <filename unknown>:0 }

这是我用来建立连接的代码:

m_client = new TcpClient("gateway.push.apple.com", 2195);
m_ssl = new SslStream(m_client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
m_ssl.AuthenticateAsClient("gateway.push.apple.com", m_certColl, System.Security.Authentication.SslProtocols.Tls, false);

来自调试器的更多信息:

m_certColl 应该包含 1 个证书,即 APNS 证书。我在调试器中确认了公钥和私钥都被填充了。RemoteCertificateValidationCallback 返回 NO SslPolicyErrors。我可以确认该链包含 3 个证书。1 包含 Apple 的 gateway.push.apple.com 公钥,1 包含 Entrust 的中间证书,1 包含 Entrust 的根证书。

我已经两次和三次检查了所有内容,但我只是不知道从这里去哪里。任何帮助将不胜感激!

4

1 回答 1

0

想通了。事实证明,当涉及到 AuthenticateAsClient 时,Windows 和 Mono(至少在 Linux 上)的行为不同。根据您的证书链,Windows 将对身份验证时使用的证书做出“最佳猜测”(因为 APNS 证书是链中唯一的证书,所以很容易猜测)

Mono 根本不会“猜测”。您必须使用 LocalCertificateSelectionCallback 指定证书。你不能像我一样让它“空”

于 2012-12-17T15:00:42.523 回答