Read SSL Certificate Details on WP8

后端 未结 4 1339
旧巷少年郎
旧巷少年郎 2021-01-03 03:25

I want to read certificate details (e.g. expiration date or CN) for security reasons.

Usually there are some properties in network classes available, that allow to

相关标签:
4条回答
  • 2021-01-03 03:44

    For WP8, you can use the StreamSocket class, which has an UpgradeToSslAsync() method that will do the TLS handshake for you as an async operation. Once that completes, you can use the .Information.ServerCertificate property to check that you got the server certificate you were expecting.

    0 讨论(0)
  • 2021-01-03 03:45

    On Windows Phone 8.1 this can be done with HttpClient, as well as with StreamSocket (as Mike suggested).
    Example for certificate validation with StreamSocket can be found here (Scenario5_Certificate in source code).

    Certificate validation with HttpClient can be done by handling the ERROR_INTERNET_INVALID_CA exception, validating the server certificate using the HttpTransportInformation class, creating new instance of HttpBaseProtocolFilter class and specifying the errors to ignore.

    Note that not all the errors are ignorable. You will receive an exception if you'll try to add Success, Revoked, InvalidSignature, InvalidCertificateAuthorityPolicy, BasicConstraintsError, UnknownCriticalExtension or OtherErrors enum values.

    I'm adding a sample code that bypasses certificate errors using HttpClient:

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Threading.Tasks;
    using Windows.Security.Cryptography.Certificates;
    using Windows.Web.Http;
    using Windows.Web.Http.Filters;
    
    namespace Example.App
    {
        public class HttpsHandler
        {
            private const int ERROR_INTERNET_INVALID_CA = -2147012851; // 0x80072f0d
    
            public static async void HttpsWithCertificateValidation()
            {
                Uri resourceUri;
                if (!Uri.TryCreate("https://www.pcwebshop.co.uk/", UriKind.Absolute, out resourceUri))
                    return;
    
                IReadOnlyList<ChainValidationResult> serverErrors = await DoGet(null, resourceUri);
                if (serverErrors != null)
                {
                    HttpBaseProtocolFilter filter = new HttpBaseProtocolFilter();
                    foreach (ChainValidationResult value in serverErrors)
                    {
                        try {
                            filter.IgnorableServerCertificateErrors.Add(value);
                        } catch (Exception ex) {
                            // Note: the following values can't be ignorable:
                            //       Success Revoked InvalidSignature InvalidCertificateAuthorityPolicy
                            //       BasicConstraintsError UnknownCriticalExtension OtherErrors
                            Debug.WriteLine(value + " can't be ignorable");
                        }
                    }
    
                    await DoGet(filter, resourceUri);
                }
            }
    
            private static async Task<IReadOnlyList<ChainValidationResult>> DoGet(HttpBaseProtocolFilter filter, Uri resourceUri)
            {
                HttpClient httpClient;
                if (filter != null)
                    httpClient = new HttpClient(filter);
                else
                    httpClient = new HttpClient();
    
                HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, resourceUri);
                bool hadCertificateException = false;
                HttpResponseMessage response;
                String responseBody;
    
                try {
                    response = await httpClient.SendRequestAsync(requestMessage);
                    response.EnsureSuccessStatusCode();
                    responseBody = await response.Content.ReadAsStringAsync();
                } catch (Exception ex) {
                    hadCertificateException = ex.HResult == ERROR_INTERNET_INVALID_CA;
                }
    
                return hadCertificateException ? requestMessage.TransportInformation.ServerCertificateErrors : null;
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-03 03:52

    After trying open source libs like bouncyCastle, supersocket or webSocket4net I tested an evaluation of a commercial lib named ELDOS SecureBlackbox. This test was successfull. Here is a code snipped, that gets the X509Certificates with all details:

    public void OpenSSL()
    {
        var c = new TElSimpleSSLClient();
        c.OnCertificateValidate += new TSBCertificateValidateEvent(OnCertificateValidate);
    
        c.Address = "myhostname.com";
        c.Port = 443;
        c.Open();
        c.Close(false);
    }
    
    private void OnCertificateValidate(object sender, TElX509Certificate x509certificate, ref TSBBoolean validate)
    {
        validate = true;
    }
    

    The validation is getting all certificates... if validate is set to true, the next certificate will be shown. That means the callback is called forreach certificate there.

    Regards Holger

    0 讨论(0)
  • 2021-01-03 03:58

    I issued a user voice request to Microsoft .NET team asking them to provide a solution for reading server SSL certificate details from portable class libraries (targeting also WP8). You can vote it here: http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/4784983-support-server-ssl-certificate-chain-inspection-in

    0 讨论(0)
提交回复
热议问题