- Home /
Unity SSL TlsException
I am using Unity to build the client for my online game. The server uses REST with JWT and I have successfully integrated that with Unity since very early on in the project. The server runs on Heroku. I am attempting to switch to SSL for production. Heroku manages certificates for me (ACM). However, Unity is now complaining when it attempts to connect to the server for the first time via HTTPS.
Here is the error message:
TlsException: Invalid certificate received from server. Error code: 0xffffffff800b010a
Mono.Security.Protocol.Tls.Handshake.Client.TlsServerCertificate.validateCertificates (Mono.Security.X509.X509CertificateCollection certificates)
From the research I've done on other posts, the root problem appears to be that the Unity version (and thus, the mono version) I am using most likely cannot handle SHA256. Here is the most closely related thread I've found, which led me to this conclusion: Unity Issue Tracker Post. Other threads have suggested downgrading the encryption or telling Mono to accept the certificate without being able to validate it. Obviously, both of those are horrible security practices. Heroku will also not allow me to downgrade the cert security, anyway. Which is smart.
I am currently on Unity 5.4.3f1. My question is whether anyone can confirm:
Is my diagnosis likely correct?
And, if so, will upgrading Unity add support for this (and at what version)?
Update: I ran mozroots --import --sync to add root certificates to mono, per some other leads that I found (apparently it includes no certificate authorities by default).
I now receive this slightly different error message:
TlsException: Invalid certificate received from server. Error code: 0xffffffff80092012
$$anonymous$$ono.Security.Protocol.Tls.Handshake.Client.TlsServerCertificate.validateCertificates ($$anonymous$$ono.Security.X509.X509CertificateCollection certificates)
This indicates that it cannot decrypt the cert, which possibly further validates my conclusion.
"Heroku" doesn't seem to be a "certificate authority (CA)". Is your certificate actually registrated by a trusted CA? As far as i remember Unity doesn't accept self-signed certificates (as they are basically useless for security). If you use a self-signed certificate on your server you have to "manually" accept it by implementing the validation yourself.
$$anonymous$$eep in $$anonymous$$d that a certificate serves two purposes:
provide initial encryption to exchange a symetric encryption key that is used to encrypt the actual traffic
verify the identity of the server.
The first point usually can be done with a self-signed certificate. It is just used to exchange the crypto key. A self-signed certificate is still "secure" as long as you actually talk to the right server.
However if you are compromised in some way and your request is redirected to another server, you can't verify the identity of that server and his certificate. Everybody can create a self-signed certificate. If you have an actual certificate that is signed by a trusted CA it should usually work just fine. However keep in $$anonymous$$d that the certificate only works on the actual server. If you use a development environment which uses a different URL / IP the certificate can't be verified as that's exactly what the certificate should prevent.
If you just accept any certificate blindly your connection is still encrypted and someone just "listening" to your conversation has no chance of decrypting your messages. The only way is a true man-in-the-middle attack who plays "proxy" in between you and the actual server.
See this SO post for more details.
As far as i remember we used actual SSL certificates in the company i worked several years ago. We did build for android and iOS and i can't really remember any problems.
Again, accepting any certificate does not "downgrade the encryption". It just prevents you from validating that you're actually talking to the right peer.
You may have also a look at this page which explains the process of buying a certificate. Note that they only recommend a self signed certificate for development / testing environments. However as i said i think that Unity does not accept self-signed certificates by default.
Heroku provisions certificates through letsencrypt.org. They are not self-signed. $$anonymous$$ine is issued by DigiCert via their high assurance CA. If I access the REST interface with chrome dev tools, I get all these details and assurance that the cert is valid and accepted.
Your experience a few years ago might depend entirely on what encryption your certificates had at the time. If they were, e.g. SHA-1, Unity would apparently have no problem with them because $$anonymous$$ono supported that in 2.0.
Hopefully, that's more to go on :-)
Ok, great to have that cleared up :) It's often a pain if you ask some counter questions and don't get any meaningful information back.
According to this SO question there seems to be some contradicting information. Some state that Unity's mono version should support SHA256 as hash algorithm for SSL certificates. Others say that it doesn't but Unity's WWW class does as it's not using $$anonymous$$ono at all to handle the connection.
Since the native implementation of the engine highly depend on the target platform i think it would help to know for what platform you build your game / application. Also which API do you use for your requests? (WWW, mono's WebRequest, UnityWebRequest, something else?).
If your target is WebGL keep in $$anonymous$$d that due to the security sandbox of the browser WWW requests are quite limited.
Answer by justindz · Jul 19, 2017 at 11:56 PM
Right, problem solved. WebRequest cannot decrypt a SHA256 cert. I was using that for the auth call, as I said, because UnityWebRequest cannot handle the JWT token exchange. I did a test call and verified that UnityWebRequest otherwise can decrypt SHA256. So the limitation is definitely Mono v2.
I switched the auth call from WebRequest to WWW (the low level api or "LLAPI" as opposed to UnityWebRequest which is the high level api or "HLAPI"). After some testing, this appears to both handle SHA256 and handle the JWT token exchange correctly.
Thus, I have a probably solution. I will need to build to and test on my target platforms. All of the above was verified through the Unity player. Thanks to @Bunny83 for the assistance--the discussion got me to where I needed to be.
TL;DR: - Unity 5.4 (and probably also 5.5 and 5.6) cannot decrypt SHA256 certificates if you use .NET WebRequests, because mono v2.X only supports SHA1. - If you can use either UnityWebRequest OR WWW, which are both Unity tools that don't depend on WebRequest, you should be okay.
Btw: SHA256 is not an encryption and can't be "decrypted". It's a Hash function with some special cryptographic properties. If you want to use the term "encryption" it's a "one-way encryption" that can't be reversed, that's the main point of it.
Answer by mustang4484 · Nov 11, 2018 at 08:31 PM
Hello i've this script for read a simple file xml inside unity:
private string filepath = "https://www.mywebsite.com/service/xml/testfile.xml";
public void Read()
{
Debug.Log("eccolo");
XDocument doc = XDocument.Load(filepath);
foreach (XElement el in doc.Root.Elements())
{
Debug.Log(string.Format("{0} {1}", el.Name, el.Attribute("id").Value));
Debug.Log(string.Format(" Attributes:"));
foreach (XAttribute attr in el.Attributes())
Debug.Log(string.Format(" {0}", attr));
Debug.Log(string.Format(" Elements:"));
foreach (XElement element in el.Elements())
Debug.Log(string.Format(" {0}: {1}", element.Name, element.Value));
}
}
And i've this error when call:
TlsException: Invalid certificate received from server. Error code: 0xffffffff800b010f Mono.Security.Protocol.Tls.Handshake.Client.TlsServerCertificate.validateCertificates (Mono.Security.X509.X509CertificateCollection certificates) Mono.Security.Protocol.Tls.Handshake.Client.TlsServerCertificate.ProcessAsTls1 ()
Can you help me please?
Thank you