【问题标题】:Read SSL Certificate Details on WP8阅读 WP8 上的 SSL 证书详细信息
【发布时间】:2013-07-18 11:34:42
【问题描述】:

出于安全原因,我想阅读证书详细信息(例如到期日期或 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 不支持这有什么原因?

问候 霍尔格

【问题讨论】:

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


    【解决方案1】:

    在 Windows Phone 8.1 上,这可以通过 HttpClientStreamSocket 完成(正如 Mike 建议的那样)。
    可以找到使用 StreamSocket 进行证书验证的示例here(源代码中的Scenario5_Certificate)。

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

    请注意,并非所有错误都可以忽略。如果您尝试添加 Success、Revoked、 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;
            }
        }
    }
    

    【讨论】:

    • 请注意,这仅适用于 Windows (Phone) 8.1,不适用于 WP 8.0。 WP 8.0 不支持 HttpRequestMessage。
    【解决方案2】:

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

    【讨论】:

    • StreamSocket.Information.ServerCertificate 属性已在 Windows Phone 8.1 中添加!
    【解决方案3】:

    我向 Microsoft .NET 团队发出了用户语音请求,要求他们提供一种解决方案,用于从可移植类库(也针对 WP8)读取服务器 SSL 证书详细信息。你可以在这里投票:http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/4784983-support-server-ssl-certificate-chain-inspection-in

    【讨论】:

      【解决方案4】:

      在尝试了 bouncyCastle、supersocket 或 webSocket4net 等开源库后,我测试了一个名为 ELDOS SecureBlackbox 的商业库的评估。本次测试成功。这是一个截取的代码,它获取 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,将显示下一个证书。这意味着回调被称为 forreach certificate 那里。

      问候 霍尔格

      【讨论】:

        猜你喜欢
        • 2011-12-13
        • 1970-01-01
        • 1970-01-01
        • 2017-04-20
        • 1970-01-01
        • 1970-01-01
        • 2012-07-06
        • 1970-01-01
        • 2019-03-08
        相关资源
        最近更新 更多