I am creating a game using Unity Engine (2017.2.0f3) on Windows 10, in which I am trying to get HTML code from a web page. As far as I know, Unity uses the C # "Mono" compiler and runtime v2.0 (based on mono --version in Unity\Editor\Data\Mono\bin ), but also v5.0.1 (based on mono --version in Unity\Editor\Data\MonoBleedingEdge\bin ). I am currently using HTML Agility Pack for parsing. When I try to access a secure HTTP site, such as dictionary.com , everything works as expected, but no matter what I do, I canβt access a secure website that supports HTTPS, such as urbandictionary.com (Edit: Apparently, the problem is connected with this site, because after importing certificates using mozroots , github.com can be accessed) and always get an exception: TlsException: The authentication or decryption has failed. I am aware that the HTML Agility Pack does not support HTTPS, and have written my code according to this answer . I tried the solution described here and here , but to no avail. I tried to run mozroots , which I found in PathTo/Unity/Editor/Data/MonoBleedingEdge/lib/mono/4.5/mozroots , with the --import , --sync and --quiet flags, but the same exception is thrown (if this worked, I am skeptical about its portability, but maybe I could implement my own version of mozroots, as suggested in the comments). In addition, I was informed that the Mono version that Unity uses does not support TLS 1.2, which is problematic. If there is no solution to this problem, are there any workarounds?
Note: abbreviated for clarity.
class MyWebClient : WebClient { protected override WebRequest GetWebRequest(Uri address) { HttpWebRequest request = base.GetWebRequest(address) as HttpWebRequest; request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip; return request; } } class GetHtml { public static void Get(string url) { string documentString = new MyWebClient().DownloadString(url); ... } } class CallingClass { public void CallingMethod() { ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
The log is as follows:
TlsException: The authentication or decryption has failed. Mono.Security.Protocol.Tls.RecordProtocol.ProcessAlert (AlertLevel alertLevel, AlertDescription alertDesc) Mono.Security.Protocol.Tls.RecordProtocol.InternalReceiveRecordCallback (IAsyncResult asyncResult) Rethrow as IOException: The authentication or decryption has failed. Mono.Security.Protocol.Tls.SslStreamBase.AsyncHandshakeCallback (IAsyncResult asyncResult) Rethrow as WebException: Error getting response stream (Write: The authentication or decryption has failed.): SendFailure System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) System.Net.HttpWebRequest.GetResponse () System.Net.WebClient.GetWebResponse (System.Net.WebRequest request) System.Net.WebClient.DownloadDataCore (System.Uri address, System.Object userToken)
Edit: I tried updating the version. The only option was to change from .Net 3.5 to 4.6 in the Project Settings-> Player menu, which is experimental. I still get an exception when the code runs, but the output log is a little different.
TlsException: The authentication or decryption has failed. Mono.Security.Protocol.Tls.RecordProtocol.EndReceiveRecord (System.IAsyncResult asyncResult) (at <eb1224ae7b184cd09343d47f8a05481b>:0) Mono.Security.Protocol.Tls.SslClientStream.SafeEndReceiveRecord (System.IAsyncResult ar, System.Boolean ignoreEmpty) (at <eb1224ae7b184cd09343d47f8a05481b>:0) Mono.Security.Protocol.Tls.SslClientStream.NegotiateAsyncWorker (System.IAsyncResult result) (at <eb1224ae7b184cd09343d47f8a05481b>:0) Rethrow as IOException: The authentication or decryption has failed. Mono.Security.Protocol.Tls.SslClientStream.EndNegotiateHandshake (System.IAsyncResult result) (at <eb1224ae7b184cd09343d47f8a05481b>:0) Mono.Security.Protocol.Tls.SslStreamBase.AsyncHandshakeCallback (System.IAsyncResult asyncResult) (at <eb1224ae7b184cd09343d47f8a05481b>:0) Rethrow as IOException: The authentication or decryption has failed. Mono.Security.Protocol.Tls.SslStreamBase.EndRead (System.IAsyncResult asyncResult) (at <eb1224ae7b184cd09343d47f8a05481b>:0) Mono.Net.Security.Private.LegacySslStream.EndAuthenticateAsClient (System.IAsyncResult asyncResult) (at <344dc4d3f1ad41809df78607b6121a41>:0) Mono.Net.Security.Private.LegacySslStream.AuthenticateAsClient (System.String targetHost, System.Security.Cryptography.X509Certificates.X509CertificateCollection clientCertificates, System.Security.Authentication.SslProtocols enabledSslProtocols, System.Boolean checkCertificateRevocation) (at <344dc4d3f1ad41809df78607b6121a41>:0) Mono.Net.Security.MonoTlsStream.CreateStream (System.Byte[] buffer) (at <344dc4d3f1ad41809df78607b6121a41>:0) System.Net.WebConnection.CreateStream (System.Net.HttpWebRequest request) (at <344dc4d3f1ad41809df78607b6121a41>:0) Rethrow as WebException: Error: SecureChannelFailure (The authentication or decryption has failed.) System.Net.WebClient.DownloadDataInternal (System.Uri address, System.Net.WebRequest& request) (at <344dc4d3f1ad41809df78607b6121a41>:0) System.Net.WebClient.DownloadString (System.Uri address) (at <344dc4d3f1ad41809df78607b6121a41>:0) System.Net.WebClient.DownloadString (System.String address) (at <344dc4d3f1ad41809df78607b6121a41>:0)