Wednesday, October 7, 2026
HomeiOS Developmentc# - Xamarin.Varieties - Certificates Pinning utilizing customized HttpMessageHandlers

c# – Xamarin.Varieties – Certificates Pinning utilizing customized HttpMessageHandlers

[ad_1]

I am engaged on a multi-platform app utilizing Xamarin.Varieties that helps Android, iOS, & UWP. I am implementing Certificates Pinning with an inside API that this utility makes use of. I am probably not an knowledgeable on the subject of SSL Certificates & I’m new to the final idea of certificates/public key pinning, although I am coming to an understanding of what must be achieved to implement this. One factor that I’m combating although is how I can confirm that I’ve the suitable public key to check with once I’m debugging the app.

Our app makes API calls utilizing a primary System.Web.Http.HttpClient, and we use a DependencyService to go a platform particular HttpMessageHandler to the shopper to make use of. As a result of we’re utilizing NSUrlSessionHandler for iOS & AndroidClientHandler for Android (UWP makes use of a HttpClientHandler), we sadly cannot make the most of the ServicePointManager.ServerCertificateValidationCallback property to deal with this, because the native handlers do not assist it. Fortunately, I have been capable of finding some pattern code that reveals how this may be achieved for the Android & iOS platforms that I am now, and I have been in a position to determine one thing that appears to work properly for UWP. The iOS/Android pattern that I have been is that this GitHub challenge: https://github.com/basdecort/Xamarin/tree/grasp/CertificatePinning

This is the code that I’ve labored out for UWP’s HttpMessageHandler that appears to do the trick

    personal static readonly string[] PublicKeys =
    {
        "3082010A0282010100<PublicKey1>0203010001" // a number of keys will probably be pinned, therefore the array
    };

    public HttpMessageHandler GetHandler(bool shouldAutoRedirect)
    {
        var retval = new HttpClientHandler
         DecompressionMethods.GZip,
            AllowAutoRedirect = shouldAutoRedirect,
            ServerCertificateCustomValidationCallback = PinPublicKey,
        ;

        return retval;
    }

    personal static bool PinPublicKey(HttpRequestMessage requestMessage, X509Certificate2 certificates, X509Chain chain, SslPolicyErrors sslPolicyErrors)
     chain == null)
            return false;

        if (sslPolicyErrors != SslPolicyErrors.None)
            return false;

        // Confirm towards the identified public key throughout the certificates
        var pk = certificates.GetPublicKeyString();

        return PublicKeys.Accommodates(pk.ToUpperInvariant());
    

Working with this code, its very clear to confirm that the general public key that I am anticipating is right. The pk variable worth contains the general public key modulus that I can see once I have a look at the certificates via Google Chrome, in between the prefix & exponent characters.

With the pattern implementations on Android & iOS although, the string I’ve to overview when debugging is not as good, and I’ve up to now struggled with decoding the general public key right into a extra readable string like I can see once I’m debugging UWP.

Android (I’ve simply included the related strategies on this pattern):

public class CustomPublicKeyManager : Java.Lang.Object, IX509TrustManager
{
    personal static readonly string[] PublicKeys; // Similar as UWP pattern code
    public void CheckServerTrusted(X509Certificate[] chain, string authType)
    {
        if (!ValidateIntermediate(chain))
        {
        //code to deal with failed verify
        }
    }

    personal bool ValidateCert(X509Certificate certificates)
    {
        var pubKeyString = Android.Util.Base64.EncodeToString(certificates.PublicKey.GetEncoded(), Android.Util.Base64Flags.Default).Substitute("n", "");
        return PublicKeys.Accommodates(pubKeyString.ToUpperInvariant());
    }

    personal bool ValidateIntermediate(X509Certificate[] chain)
    {
        if (chain.Size <= 1)
        {
            return false;
        }
        return ValidateCert(chain[1]);
    }
}

On this case, pubKeyString shops a string with a prefix of “MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA” and an exponent of “QIDAQAB” (with the encoded public key in between). I’ve tried looking for methods to transform this string to one thing extra readable and simpler to confirm (and I’ve additionally performed round with the totally different strategies I’ve seen out there to me on the Android objects), however I’ve had no such luck. Is it doable to transform this encoded string to the worth that I see in UWP, and if that’s the case, is there an excellent instance of how that may be achieved?

I am going through an identical concern of encountering an encoded string in my try and make a customized implementation of NSUrlSessionHandlerDelegate.DidReceiveChallenge that features pinning on iOS, so I’ve the identical query for this platform as I do for Android.

        public override void DidReceiveChallenge(NSUrlSession session, NSUrlSessionTask process, NSUrlAuthenticationChallenge problem, Motion<NSUrlSessionAuthChallengeDisposition, NSUrlCredential> completionHandler)
        {
            // different code above. That is the pinning code
            var serverCertChain = problem.ProtectionSpace.ServerSecTrust;
            if (ValidateIntermediatePublicKey(serverCertChain))
            {
                completionHandler(NSUrlSessionAuthChallengeDisposition.PerformDefaultHandling, problem.ProposedCredential);
            }
            else
            {
                completionHandler(NSUrlSessionAuthChallengeDisposition.CancelAuthenticationChallenge, null);
            }
        }

        personal static bool ValidateIntermediatePublicKey(SecTrust securitySecTrust)
        {
            var first = securitySecTrust[1].DerData;
            var firstString = first.GetBase64EncodedString(NSDataBase64EncodingOptions.None);

            // The right way to convert firstString right into a extra readable format?

            return PublicKeys.Accommodates(firstString.ToUpperInvariant());
        }

[ad_2]

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments