如何在UWP应用中将客户端证书用于HTTP请求

时间:2018-08-14 19:34:59

标签: c# uwp

我正在编写一个应用,该应用需要发出一些使用客户端证书的HTTPs请求。但是,我找不到有关如何安装证书然后加载证书以供使用的任何文档。我知道您可以通过制作HttpBaseProtocolFilter并添加证书来使用证书,但是如何在此处加载证书以供使用?如果您的客户端证书带有.pfx文件,那么如何与软件包一起安装?

谢谢!

1 个答案:

答案 0 :(得分:0)

对于它的价值,我最终使用Portable.BouncyCastle NuGet包和一些UWP API的组合来弄清楚。下面是我所做的一些示例代码(伪伪代码):

// Asymmetric key pair
RsaKeyPairGenerator keyPairGenerator = new RsaKeyPairGenerator();
keyPairGenerator.Init(
    new KeyGenerationParameters(
        new SecureRandom(new CryptoApiRandomGenerator()), 2048));
AsymmetricCipherKeyPair keyPair = keyPairGenerator.GenerateKeyPair();

// Create certificate
X509V3CertificateGenerator generator = new X509V3CertificateGenerator();
generator.SetSubjectDN("foo");
generator.SetIssuerDN("foo");
generator.SetSerialNumber(new BigInteger("12345").Abs());
generator.SetNotBefore(DateTime.UtcNow);
generator.SetNotAfter(DateTime.UtcNow + TimeSpan.FromYears(1));
generator.SetPublicKey(keyPair.Public);

BouncyCastleX509Certificate certificate =
    generator.Generate(
        new Asn1SignatureFactory("SHA1WithRSA", keyPair.Private));

// Create PKCS12 certificate bytes.
Pkcs12Store store = new Pkcs12Store();
X509CertificateEntry certificateEntry = new X509CertificateEntry(certificate);
string friendlyName = "Friendly Name";
string password = "password";
store.SetCertificateEntry(friendlyName, certificateEntry);
store.SetKeyEntry(
    friendlyName,
    new AsymmetricKeyEntry(keyPair.Private),
    new X509CertificateEntry[] { certificateEntry });
string pfxData;
using (MemoryStream memoryStream = new MemoryStream(512))
{
    store.Save(memoryStream, password.ToCharArray(), this.SecureRandom);
    pfxData = CryptographicBuffer.EncodeToBase64String(memoryStream.ToArray().AsBuffer());
}

// Add the certificate to the cert store
await CertificateEnrollmentManager.ImportPfxDataAsync(
    pfxData,
    password,
    ExportOption.NotExportable,
    KeyProtectionLevel.NoConsent,
    InstallOptions.DeleteExpired,
    friendlyName);

// Read the UWP cert from the cert store
Certificate uwpCertificate =
    (await CertificateStores.FindAllAsync(
        new CertificateQuery { FriendlyName = friendlyName }))[0];

// Create the UWP HTTP client.
HttpBaseProtocolFilter filter = new HttpBaseProtocolFilter();
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.Untrusted);
filter.IgnorableServerCertificateErrors.Add(ChainValidationResult.InvalidName);
filter.ClientCertificate = uwpCertificate;
HttpClient httpClient = new HttpClient(filter);

// Profit!