Unity - unable to send HTTPS request due to CryptographicException

I try to send an https request to my remote server, but I always get the following exception:

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 

At first, I thought it was a certificate verification problem, so before submitting the request, I added the following code:

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

It turns out that ServerCertificateValidationCallback was not even called, and the exception was due to "Plain SSL" or "SSL ciphers . "

Please note that my remote server URL is https://_my_app_.herokuapp.com/_path_ . Oddly enough, if I change the URL to any other https server, such as https://www.google.com or https://www.facebook.com , I don't get an exception and the request will succeed.

It seems that the Mono implementation used by Unity does not support the heroku script set (I can guarantee this because I recently developed a MonoTouch application that was able to connect to the same server).

Is this a problem with the client or server? Should I add hacker code on the client side or change the server configuration?

+6
source share
4 answers

I could not find the cause, but found a solution to the problem.

I used UnityHTTP - " TcpClient -based HTTP Library" - to execute HTTP requests. Switching to the Unity WWW class , all https requests sent to my heroku server succeeded. I learned that when using the UnityHTTP library UnityHTTP Unity tried to check crossdomain.xml on port 843, and when using the WWW class did this on port 80.

Maybe the UnityHTTP implementation deals with low-level materials that are currently not compatible with heroku servers, I will not investigate this anymore, but I will still open the problem in the UnityHTTP github repository.

+2
source

I do not have a complete answer, but this is not a ciphersuite problem; stacktrace shows that this is a certificate verification problem at a low level of signature verification before the callback is invoked. OID 1.2.840.113549.1.1.11 is SHA256withRSA, and the security provider (s) in the client does not process it. You do a good job with major servers like google and facebook because they continue to use certificates signed by SHA1withRSA, precisely because client / browser support for SHA256 + RSA is not yet universal, although more and more often. https://cabforum.org/baseline-requirements-documents/ requires RSA2048 this year (January 2014) unconditionally, but allows SHA1 "while SHA-256 [verification] is widely supported by the browsers used by a significant part of the relying parties around the world."

OTOH SHA1 does not have much safety margin, many people insist on SHA256, and Digicert seems to be among the more complex pushers: http://www.digicert.com/transitioning-to-sha-2.htm . The certificate that I see from herokuapp.com was recently released (2014-01-21), so it could be a deliberate choice to "allow better security" or just "use what is convenient, and Digicert gave us that." FWIW I observe id.heroku.com and www.heroku.com with the SHA1 + RSA certificate (2048) from 2013-10-12. If you cannot force your client to correct for SHA256 + RSA, and the hero is ready, they can obtain and use the SHA1 + RSA certificate at the moment, but you most likely will still need a real fix later.

As for this, How can I sign a file using RSA and SHA256 with .NET? indicates that for a dot-net signature (MS) with SHA256 + RSA requirements for the violin of the encryption service provider is not the default, and the IME check usually matches the signature. I do not use Mono or know that there is the same or similar problem, but this is the area where I would look first.

+3
source

Like Unity 4.3, Unity Mono does not support SHA-256 for SSL certificates. Supported "best" - SHA-1. We used GoDaddy (I know, I know) to issue a certificate, and, fortunately, they had a web page where we could reconnect the certificate from SHA-256 to SHA-1. Now the SSL certificate works fine.

It is not possible to find a CA that issues the SHA-1 certificate, so you will have to reapply it again.

Unity WWW-class is written in C ++ and does not go through mono. This is why you can connect to https through the WWW, but not through the UnityHTTP plugin.

+2
source

sha-256 (algorithm 1.2.840.113549.1.1.11) should work with Unity version 2.5.3. https://github.com/Unity-Technologies/mono/pull/134/files Welcome

0
source

All Articles