0

I'm trying to communicate with a backend server using SSL. I'm trying using HttpClient from the System.Net.Http library, but I couldn't get it working. This is my code (Debug.Log is just a print since I'm using Unity):

public static async Task DownloadPageAsync(string web)
 {
     try
     {
         HttpClient cl = new HttpClient();
         string body = await cl.GetStringAsync(new Uri(web));

         Debug.Log(web);
     }
     catch (HttpRequestException e)
     {
         Debug.Log(e.InnerException.Message);
     }
     catch (Exception ex)
     {
         Debug.Log(ex.ToString());
     }
 }

When I try it in a web with a bad certificate, it gives: "Error: TrustFailure (The authentication or decryption has failed.)", which is fine. The problem is that good certificates also triggers an error: "Error: SecureChannelFailure (The authentication or decryption has failed.)".

I've saw other answers saying that simply accepting all the certificates works fine, but I need to check if it's a valid certificate or not.

¿Is there a way of doing it with HttpClient? ¿Or with some other class?

Btw, I'm only using it to send POST request, and receiving a simple string.

Thank you!

  • Where did you specify the client certificate? Once you specify it you can enable capi2, https://blogs.msdn.microsoft.com/benjaminperkins/2013/09/30/enable-capi2-event-logging-to-troubleshoot-pki-and-ssl-certificate-issues/ for troubleshooting – Johnny Jan 20 '19 at 19:04
  • I didn't know that I need to specify the client certificate as I didn't saw it in the MSDN example. Is there an example of doing it? – Miguel Lahoz Jan 20 '19 at 19:51
  • You need if you use certificate based authentication. https://www.google.com/amp/s/blog.pedrofelix.org/2012/12/16/using-httpclient-with-ssltls/amp/ – Johnny Jan 20 '19 at 19:55
  • Okey, I'll try it – Miguel Lahoz Jan 20 '19 at 20:51
  • I just tried it using the HttpClientHandler (the WebRequestHandler gives me an error) and it gives the same error. It also added a new error, in which a web with a expired cert is the only one that works. – Miguel Lahoz Jan 20 '19 at 21:01
  • Use then CAPI2 and EventViewer to get more insights about the error... – Johnny Jan 20 '19 at 21:07
  • I'm not getting anything logged in the EventViewer – Miguel Lahoz Jan 20 '19 at 22:19
  • Possible duplicate of [Make Https call using HttpClient](https://stackoverflow.com/questions/22251689/make-https-call-using-httpclient) – derHugo Jan 21 '19 at 07:22

1 Answers1

0

For UnityWebRequest since Unity 2018.1 there is the UnityWebRequest.certificateHandler e.g.

IEnumerator GetRequest(string uri)
{
     UnityWebRequest request = UnityWebRequest.Get(uri);
     request.certificateHandler = new AcceptAllCertificatesSignedWithASpecificPublicKey();

     yield return request.SendWebRequest ();
     if (request.isNetworkError)
     {
         Debug.Log("Something went wrong, and returned error: " + request.error);
     }
     else
     {
         // Show results as text
         Debug.Log(request.downloadHandler.text);
     }
}

And the implementation of the example CertificateHandler:

using UnityEngine.Networking;
using System.Security.Cryptography.X509Certificates;
using UnityEngine;
// Based on https://www.owasp.org/index.php/Certificate_and_Public_Key_Pinning#.Net
class AcceptAllCertificatesSignedWithASpecificPublicKey: CertificateHandler
{
    // Encoded RSAPublicKey
    private static string PUB_KEY = "mypublickey";
    protected override bool ValidateCertificate(byte[] certificateData)
    {
        X509Certificate2 certificate = new X509Certificate2(certificateData);
        string pk = certificate.GetPublicKeyString();
        if (pk.ToLower().Equals(PUB_KEY.ToLower()))
        {
            return true;
        }

        return false;
    }
}

(Source)


For HttpClient see Make Https call using HttpClient

derHugo
  • 83,094
  • 9
  • 75
  • 115
  • I tried it and works fine, but I have one question. SSL communication is encrypted, so using HTTPS with UnityWebRequest encrypts the connection? – Miguel Lahoz Jan 21 '19 at 10:37