Ssl Unity-由于加密异常,无法发送HTTPS请求

Ssl Unity-由于加密异常,无法发送HTTPS请求,ssl,https,mono,unity3d,certificate,Ssl,Https,Mono,Unity3d,Certificate,我正在尝试向我的远程服务器发送一个https请求,但我总是遇到以下异常: Exception: System.IO.IOException: The authentication or decryption has failed. ---> System.ArgumentException: certificate ---> System.Security.Cryptography.CryptographicException: Unsupported hash algorithm:

我正在尝试向我的远程服务器发送一个https请求,但我总是遇到以下异常:

Exception: System.IO.IOException: The authentication or decryption has failed. ---> System.ArgumentException: certificate ---> System.Security.Cryptography.CryptographicException: Unsupported hash algorithm: 1.2.840.113549.1.1.11
  at Mono.Security.X509.X509Certificate.VerifySignature (System.Security.Cryptography.RSA rsa) [0x00000] in <filename unknown>:0 
  at Mono.Security.X509.X509Certificate.VerifySignature (System.Security.Cryptography.AsymmetricAlgorithm aa) [0x00000] in <filename unknown>:0 
  at System.Security.Cryptography.X509Certificates.X509Chain.IsSignedWith (System.Security.Cryptography.X509Certificates.X509Certificate2 signed, System.Security.Cryptography.AsymmetricAlgorithm pubkey) [0x00000] in <filename unknown>:0 
  at System.Security.Cryptography.X509Certificates.X509Chain.Process (Int32 n) [0x00000] in <filename unknown>:0 
  at System.Security.Cryptography.X509Certificates.X509Chain.ValidateChain (X509ChainStatusFlags flag) [0x00000] in <filename unknown>:0 
  at System.Security.Cryptography.X509Certificates.X509Chain.Build (System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at System.Security.Cryptography.X509Certificates.X509Chain.Build (System.Security.Cryptography.X509Certificates.X509Certificate2 certificate) [0x00000] in <filename unknown>:0 
  at System.Net.Security.SslStream+<BeginAuthenticateAsClient>c__AnonStorey7.<>m__A (System.Security.Cryptography.X509Certificates.X509Certificate cert, System.Int32[] certErrors) [0x00000] in <filename unknown>:0 
  at Mono.Security.Protocol.Tls.SslClientStream.OnRemoteCertificateValidation (System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Int32[] errors) [0x00000] in <filename unknown>:0 
  at Mono.Security.Protocol.Tls.SslStreamBase.RaiseRemoteCertificateValidation (System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Int32[] errors) [0x00000] in <filename unknown>:0 
  at Mono.Security.Protocol.Tls.SslClientStream.RaiseServerCertificateValidation (System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Int32[] certificateErrors) [0x00000] in <filename unknown>:0 
  at Mono.Security.Protocol.Tls.Handshake.Client.TlsServerCertificate.validateCertificates (Mono.Security.X509.X509CertificateCollection certificates) [0x00000] in <filename unknown>:0 
  at Mono.Security.Protocol.Tls.Handshake.Client.TlsServerCertificate.ProcessAsTls1 () [0x00000] in <filename unknown>:0 
  at Mono.Security.Protocol.Tls.Handshake.HandshakeMessage.Process () [0x00000] in <filename unknown>:0 
  at (wrapper remoting-invoke-with-check) Mono.Security.Protocol.Tls.Handshake.HandshakeMessage:Process ()
  at Mono.Security.Protocol.Tls.ClientRecordProtocol.ProcessHandshakeMessage (Mono.Security.Protocol.Tls.TlsStream handMsg) [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 
事实证明,
ServerCertificateValidationCallback
甚至没有被调用和调用

请注意,我的远程服务器URL是
https://_my_app_.herokuapp.com/_path_
。 奇怪的是,如果我将URL更改为任何其他https服务器,例如
https://www.google.com
https://www.facebook.com
我没有得到异常,请求成功

看起来Unity使用的Mono实现不支持heroku的密码套件(我可以保证这一点,因为我最近开发了一个能够连接到同一台服务器的MonoTouch应用程序)


这是客户机问题还是服务器问题?我应该在客户端添加一些黑客代码还是应该更改服务器的配置?

我没有完整的答案,但这不是密码套件问题;stacktrace显示,在涉及回调之前,验证签名的低级别是一个证书验证问题。OID 1.2.840.113549.1.1.11是带有RSA的SHA256,客户端中的安全提供商没有处理它。您可以与google和facebook等主流服务器配合使用,因为它们继续使用签名为SHA1 with RSA的证书,这正是因为对SHA256+RSA的客户端/浏览器支持虽然越来越普遍,但尚未普及。今年(2014年1月)无条件要求RSA2048,但允许SHA1“直到世界上大部分依赖方使用的浏览器广泛支持SHA-256[verify]”

OTOH SHA1没有太多的安全余量,很多人都在争取SHA256,Digicert似乎是其中一个更难的推动者:。我在herokuapp.com上看到的证书是最近发布的(2014-01-21),因此这可能是一个深思熟虑的选择“让我们提高安全性”或只是“使用方便的东西,而Digicert给了我们这个”。FWIW我观察id.heroku.com和www.heroku.com从2013年10月12日起使用SHA1+RSA(2048)证书。如果您无法为您的客户机修复SHA256+RSA,并且heroku愿意,他们现在可以获取并使用SHA1+RSA证书,但您以后可能仍然需要真正的修复


关于这一点,表明对于使用SHA256+RSA的(MS)点网签名,需要修改非默认加密提供程序,IME验证通常与签名相同。我不使用Mono,也不知道是否存在相同或类似的问题,但这是我首先考虑的领域。

我找不到原因,但找到了问题的解决方案

我使用“基于TcpClient的HTTP库”来执行HTTP请求。 通过切换到Unity的allhttps发送到我的heroku服务器的请求成功。我发现,当使用
unityhtp
library时,Unity试图在843端口上执行
crossdomain.xml
验证,同时,当使用
WWW class
时,在端口80上执行此类验证


也许
UnityHTTP
的实现处理的是目前与heroku服务器不兼容的低级内容,我不会对此进行进一步调查,但我还是会在
UnityHTTP
的github存储库中发现一个问题。

从Unity 4.3开始,Unity的Mono版本不支持SSL证书的SHA-256。支持的“最佳”是SHA-1。我们曾使用GoDaddy(我知道,我知道)颁发证书,幸运的是,他们有一个网页,我们可以将证书从SHA-256重新键入SHA-1。现在SSL证书工作得很好

几乎不可能找到将颁发SHA-1证书的CA,因此您必须重新设置密钥


统一的WWW类是用C++编写的,不经过单声道。这就是为什么您可以通过WWW连接到https,但不能通过unityhtp插件连接到https。

sha-256(算法1.2.840.113549.1.1.11)应该从2.5.3开始使用Unity。不客气

谢谢!你知道这要花多长时间才能发布到Unity版本吗?我相信你很清楚,这几乎是一年后的事了,但这已经被修复了很长时间了。:)考虑到SHA-1作为一个有效的SSL证书被贬低,这个答案可能不是一个好办法。
ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, ssl) => true;