什么';这是在给定SecureString密码的情况下从PFX文件保存和加载CngKey的最简单方法

本文关键字:文件 PFX 情况下 保存 方法 最简单 CngKey 加载 密码 SecureString 什么 | 更新日期: 2023-09-27 18:27:18

给定一个新生成的可导出公钥/私钥对CngKey和一个SecureString,我需要进行哪些API调用才能创建一个包含使用密码保护的公钥/私钥内容的PFX文件?给定一个PFX文件和一个SecureString密码,需要什么API调用才能将内容加载到CngKey中?

基类库似乎没有提供这一点,但我更喜欢p/invoke,而不是依赖第三方库。我还想避免将解密的私钥存储在内存中,即使有一种方法(类似于SecureString)可以在PFX和CngKey之间保持其安全。

当我试图理解这些概念时,我能找到的所有例子都涉及自签名证书。这不是证书,只是我想要密码保护的公共/私人blob。我不想将blob导入存储区,我想从PFX文件中使用它。

这是我自己所能做到的:

using (var key = CngKey.Create(CngAlgorithm.ECDsaP521, null, new CngKeyCreationParameters { ExportPolicy = CngExportPolicies.AllowExport, KeyUsage = CngKeyUsages.Signing }))
using (var algorithm = new ECDsaCng(key))
{
    var container = new X509Certificate2();
    container.PrivateKey = algorithm; // Exception: m_safeCertContext is an invalid handle
    var pfxFileContents = container.Export(X509ContentType.Pkcs12, password);
    using (var pfxFile = File.Create("text.pfx"))
        pfxFile.Write(pfxFileContents, 0, pfxFileContents.Length);
}

什么';这是在给定SecureString密码的情况下从PFX文件保存和加载CngKey的最简单方法

在这种情况下,最好的解决方案是引用Security.Cryptography.dll。这个开源库是稳定的,如果我理解正确的话,可能已经合并到.NET Framework中;它背后的开发人员来自团队。

CngKey存储在受SecureString保护的PFX流中:

// NB! X509Certificate2 does not implement IDisposable in .NET 4.5.2, but it does in 4.6.1.
using (var cert = key.CreateSelfSignedCertificate(new X509CertificateCreationParameters(new X500DistinguishedName("CN=Example Name"))
{
    StartTime = DateTime.Now,
    EndTime = DateTime.MaxValue,
    TakeOwnershipOfKey = true,
    SignatureAlgorithm = X509CertificateSignatureAlgorithm.ECDsaSha256 // Manually match your CngKey type (RSA/ECDSA)
}))
{
    File.WriteAllBytes(pfxPath, cert.Export(X509ContentType.Pkcs12, pfxPassword));
}

从受SecureString保护的PFX流加载CngKey

// NB! X509Certificate2 does not implement IDisposable in .NET 4.5.2, but it does in 4.6.1.
using (var cert = new X509Certificate2(pfxPath, pfxPassword))
    return cert.GetCngPrivateKey();