使用 Windows RT 的客户端证书(windows 8.1/windows phone 8.1)

Posted

技术标签:

【中文标题】使用 Windows RT 的客户端证书(windows 8.1/windows phone 8.1)【英文标题】:Using Client certificates for Windows RT (windows 8.1/windows phone 8.1) 【发布时间】:2014-11-04 00:40:09 【问题描述】:

我正在尝试 windows 8.1 和 windows phone 8.1 的一个新功能,即证书存储以及在服务器端使用客户端证书进行客户端身份验证的可能性。但是,我在使用此功能时遇到了问题。

我有一个在 IIS express 上运行的经过基本测试的 WCF 服务。 IIS express 配置为支持SSL 和客户端证书。 在 IIS 的配置文件(configurationhost.config)中我设置了这个:

<access sslFlags="SslRequireCert" /> (tried also SslNegotiateCert)
<clientCertificateMappingAuthentication enabled="true" />

我在 Windows RT 应用程序中添加了客户端证书,如下所示:

//Install the self signed client cert to the user certificate store
string CACertificate = null;
try

    Uri uri = new Uri("ms-appx:///Assets/AdventureWorksTestClient1.pfx");
    var file = await Windows.Storage.StorageFile.GetFileFromApplicationUriAsync(uri);
    IBuffer buffer = await FileIO.ReadBufferAsync(file);
    using (DataReader dataReader = DataReader.FromBuffer(buffer))
    
       byte[] bytes = new byte[buffer.Length];
       dataReader.ReadBytes(bytes);
       // convert to Base64 for using with ImportPfx
       CACertificate = System.Convert.ToBase64String(bytes);
    
    await CertificateEnrollmentManager.UserCertificateEnrollmentManager.ImportPfxDataAsync(
            CACertificate,
            "",
            ExportOption.Exportable,
            KeyProtectionLevel.NoConsent,
            InstallOptions.None,
            "ClientCert1");
 
 catch (Exception ex)
 ...

然后我使用 HttpBaseProtocolFilter 以这种方式添加客户端证书:

IReadOnlyCollection<Certificate> certs = await CertificateStores.FindAllAsync(query);

HttpBaseProtocolFilter bpf = new HttpBaseProtocolFilter();
if (certs.Count > 0)

    cert = certs.ElementAt(0);
    bpf.ClientCertificate = cert;

HttpClient httpClient = new HttpClient(bpf);
....

然后请求:

var resp = await httpClient.GetAsync(new Uri(serviceURL));

这行代码产生了这个异常:

System.Exception: Exception from HRESULT: 0x80072F7D
  at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
  at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
  at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
  at JumpStartCertificateDemo.MainPage.<btnCallService_Click>d__0.MoveNext()

我 100% 确定我已经在 localhost(本地计算机)和应用程序端导入了正确的证书。通过浏览器调用服务正常。 (提示我提供客户端证书),所以在应用程序中提供客户端证书肯定有一些问题。

有人可以帮我解决这个问题吗?谢谢。

【问题讨论】:

您看到的可能是因为对证书的请求是 C# 中的 WebException,您需要通过捕获它来处理它。由于您无法尝试捕获,因此您需要删除等待并使用任务来验证 t.IsFaulted 中的结果并检查 t.Exception; Pedro 感谢您的评论,但我发现了异常(我知道如何使用它们),存在问题,不应该有异常,因为调用 get 请求应该作为我正在附加客户端证书,并从浏览器和 android 请求作品。 不,在 .Net 中,根据请求选项,证书请求会引发异常,这就是它的工作方式,我已经做了很多次。当您在 4XX 响应中收到某些内容时,将引发 WebException。使用 fiddler 查看您收到的回复。 我明白,但请求应该可以。不应有 4xx 响应。 这是基本的 HTTP 协议 每次您需要对自己进行身份验证时,您都会收到一个身份验证质询,这是一个 4XX 响应打开提琴手并打开您的电子邮件并查看 4XX 消息。有时您可以预先进行身份验证,但即使在这种情况下,有时它也需要几条消息,这就是 HTTP 的工作原理,而且没有办法绕过它。 【参考方案1】:

问题可能与您使用的证书的有效性有关。

默认情况下,.Net 拒绝使用无效或不受信任的证书建立 https 连接。

通常证书无效,因为它是由不受信任的机构(自签名证书)生成的,或者是因为站点的地址未包含在证书的有效地址列表中。

在.Net中这个限制可以放宽,看这个讨论 C# Ignore certificate errors?

【讨论】:

以上是关于使用 Windows RT 的客户端证书(windows 8.1/windows phone 8.1)的主要内容,如果未能解决你的问题,请参考以下文章

Windows机器证书文件映射

如何在 Nodejs 中使用来自 Windows 应用商店的服务器证书

Surface RT在Win10中安装UWP软件,证书签名已解决

发送带有证书的 Windows Phone 推送通知?

UWP Windows应用商店应用上的TLS客户端证书身份验证

WCF 客户端证书验证 + Windows 身份验证