【问题标题】:Unity - Unable to send HTTPS request due to CryptographicExceptionUnity - 由于 CryptographicException 无法发送 HTTPS 请求
【发布时间】:2014-03-12 22:05:09
【问题描述】:

我正在尝试向我的远程服务器发送 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 

一开始我以为是证书验证问题,所以在发送请求前添加了如下代码:

ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, ssl) => true;

原来ServerCertificateValidationCallback 甚至没有被调用,the exception was related to 'Plain SSL' or 'SSL ciphers'

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

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

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

【问题讨论】:

    标签: ssl https mono unity3d certificate


    【解决方案1】:

    sha-256(算法 1.2.840.113549.1.1.11)应该在 Unity 2.5.3 中使用。 https://github.com/Unity-Technologies/mono/pull/134/files不客气

    【讨论】:

    • 谢谢!知道这可能需要多长时间才能成为 Unity 版本吗?
    • 我相信你已经很清楚了,这是将近一年后的事情,但这个问题已经修复了很长时间。 :)
    【解决方案2】:

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

    几乎不可能找到可以颁发 SHA-1 证书的 CA,因此您必须重新输入密钥。

    Unity 的 WWW 类是用 C++ 编写的,不经过单声道。这就是为什么你可以通过 WWW 而不是通过 UnityHTTP 插件连接到 https。

    【讨论】:

    • 考虑到 SHA-1 作为有效的 SSL 证书被贬低,这个答案可能不是一个好的解决方法。
    【解决方案3】:

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

    我使用UnityHTTP——一个“基于 TcpClient 的 HTTP 库”——来执行 HTTP 请求。 通过切换到 Unity 的 WWW class,发送到我的 heroku 服务器的所有 https 请求都成功了。我发现当使用UnityHTTP库时Unity试图在843端口上执行crossdomain.xml验证,同时当使用WWW class在端口80上执行这样的验证。

    也许UnityHTTP 的实现处理当前与heroku 服务器不兼容的低级内容,我不会对此进行进一步调查,但无论如何我都会在UnityHTTP 的github 存储库上打开一个问题。

    【讨论】:

      【解决方案4】:

      我没有完整的答案,但这不是密码套件问题;堆栈跟踪显示这是在涉及回调之前验证签名的低级别证书验证问题。 OID 1.2.840.113549.1.1.11 是 SHA256withRSA,并且客户端中的安全提供程序没有处理它。您可以在 google 和 facebook 等主流服务器上正常工作,因为它们继续使用 SHA1withRSA 签名的证书,正是因为客户端/浏览器对 SHA256+RSA 的支持尚未普遍,尽管越来越普遍。 https://cabforum.org/baseline-requirements-documents/ 今年(2014 年 1 月)无条件要求 RSA2048,但允许 SHA1,“直到 SHA-256 [验证] 被全球大部分依赖方使用的浏览器广泛支持。”

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

      对此,How can I sign a file using RSA and SHA256 with .NET? 表示对于(MS)使用 SHA256+RSA 的 dot-net 签名需要使用非默认加密提供程序,并且 IME 验证通常与签名相同。我不使用 Mono,也不知道那里是否存在相同或相似的问题,但这是我首先要看的领域。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-08-21
        • 2011-10-19
        • 2016-12-27
        • 2020-10-18
        • 2011-05-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多