阅读WP8上的SSL证书详细信息

时间:2013-07-19 08:46:30

标签: ssl windows-phone-8 network-programming tcpclient bouncycastle

出于安全原因,我想阅读证书详细信息(例如到期日期或CN)。

通常网络类中有一些属性可用于检查证书。这在WP8实现中缺失。

此外,我尝试创建一个SslStream,但也无法获得任何证书详细信息,例如.net 4.5上的RemoteCertificate

var sslStream = new SslStream(new NetworkStream(e.ConnectSocket));

SslStream缺少与安全相关的所有内容。所以看起来BountyCastle和其他库也无法获得证书,因为底层框架不支持它。

所以我的问题是:

  1. 我可以使用其他方法阅读WP8上的CN或其他Certificate详细信息吗?
  2. 如果没有,您如何使用SSL Pinning或客户端证书验证等技术在WP8上创建严格保护的应用程序(线路银行),是否有任何理由说明WP8不支持此功能?
  3. 此致 霍尔格

4 个答案:

答案 0 :(得分:2)

我向Microsoft .NET团队发出了一个用户语音请求,要求他们提供从便携式类库中读取服务器SSL证书详细信息的解决方案(同时针对WP8)。您可以在此处投票:http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/4784983-support-server-ssl-certificate-chain-inspection-in

答案 1 :(得分:2)

在Windows Phone 8.1上,可以使用HttpClient以及StreamSocket(如Mike建议的那样)完成此操作。
可以找到使用StreamSocket进行证书验证的示例here(源代码中的Scenario5_Certificate)。

使用HttpClient进行证书验证可以通过处理ERROR_INTERNET_INVALID_CA异常,使用HttpTransportInformation类验证服务器证书,创建HttpBaseProtocolFilter类的新实例并指定要忽略的错误来完成。

请注意,并非所有错误都是可忽略的。如果您尝试添加成功,撤销,则会收到例外情况, InvalidSignature,InvalidCertificateAuthorityPolicy,BasicConstraintsError,UnknownCriticalExtension或OtherErrors枚举值。

我添加了一个使用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;
        }
    }
}

答案 2 :(得分:1)

在尝试了bouncyCastle,supersocket或webSocket4net之类的开源库之后,我测试了一个名为ELDOS SecureBlackbox的商业lib的评估。这个测试是成功的。这是一个剪切的代码,它获取X509Certificates的所有详细信息:

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;
}

验证是获取所有证书...如果validate设置为true,将显示下一个证书。这意味着在那里调用了回调证书。

此致 霍尔格

答案 3 :(得分:0)

对于WP8,您可以使用StreamSocket类,它具有UpgradeToSslAsync()方法,可以作为异步操作为您执行TLS握手。完成后,您可以使用.Information.ServerCertificate属性检查您是否获得了预期的服务器证书。