我正在尝试在我的应用程序中实现Https客户端身份验证,但是我找不到有关如何执行此操作的文档。
通过查看MSDN文档,我想到了这个
// Certificate file in DER format (.cer or .p7b)
string CountriesFile = @"Assets\https-client.keystore.cer";
StorageFolder InstallationFolder = Windows.ApplicationModel.Package.Current.InstalledLocation;
StorageFile file = await InstallationFolder.GetFileAsync(CountriesFile);
// Read the file into a buffer
IBuffer buffer = await Windows.Storage.FileIO.ReadBufferAsync(file);
// Create the Certificate object
Certificate ClientCert = new Certificate(buffer);
HttpBaseProtocolFilter aHBPF = new HttpBaseProtocolFilter();
aHBPF.ClientCertificate = ClientCert;
// Create our http client and send the request.
HttpClient httpClient = new HttpClient(aHBPF);
HttpResponseMessage response = await httpClient.SendRequestAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead).AsTask(cts.Token);
我将这段代码放在一起查看HttpClient,HttpBaseProtocolFilter和Certificate的文档。假设我应该具有所需格式的证书,然后将文件读入
Certificate
类。上面的代码不起作用,并引发此错误
An exception of type 'System.ArgumentException' occurred in MyLib.DLL but was not handled in user code
WinRT information: The certificate specified is missing the required private key information.
我已经测试了服务器设置,并且可以通过浏览器与客户端身份验证一起使用,这使我得出两个可能的结论。
证书文件的格式错误(尽管我希望构建
Certificate
类时会引发异常)。这不是预期的方式!
有人知道应该怎么做吗?
最佳答案
看来您必须在用户级别安装证书,然后才能在Windows Store App中有效地将其用于客户端身份验证。
// Needs to be a PKCS12 (p12/pfx) file
string certPath = @"Assets\https-client.keystore.p12";
StorageFile file = await Windows.ApplicationModel.Package.Current.InstalledLocation.GetFileAsync(certPath);
IBuffer buffer = await FileIO.ReadBufferAsync(file);
string certData = CryptographicBuffer.EncodeToBase64String(buffer);
// Will ask the user if they want this app to install the certificate if its not already installed.
await CertificateEnrollmentManager.UserCertificateEnrollmentManager.ImportPfxDataAsync(
certData,
"PASSWORD",
ExportOption.NotExportable,
KeyProtectionLevel.NoConsent,
InstallOptions.None,
"MyFriendlyName");
现在已经安装了证书,可以在证书存储中使用它。
var certificate = await CertificateStores.FindAllAsync(new CertificateQuery() { FriendlyName = "MyFriendlyName" });
ClientCert = certificate.Single();
HttpBaseProtocolFilter aHBPF = new HttpBaseProtocolFilter();
aHBPF.ClientCertificate = ClientCert;
// Create our http client and send the request.
HttpClient httpClient = new HttpClient(aHBPF);
HttpResponseMessage response = await httpClient.SendRequestAsync(httpRequest, HttpCompletionOption.ResponseHeadersRead).AsTask(cts.Token);
我希望能够使证书仅对应用程序可用,如果我找到了解决方法,它将更新此答案。