c# - 在给定 SecureString 密码的情况下,从 PFX 文件保存和加载 CngKey 的最简单方法是什么?

标签 c# cryptography pfx

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

看起来基类库没有提供这个,但我更喜欢 p/invoke 而不是依赖第三方库。如果有办法(类似于 SecureString)在 PFX 和 CngKey 之间保持安全,我也想避免将解密的私钥存储在内存中,即使是暂时的。

在我努力思考这些概念时,我能找到的所有示例都涉及自签名证书。这不是证书,只是我想用密码保护的公共(public)/私有(private) 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);
}

最佳答案

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

CngKey 存储在 SecureString protected 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();

关于c# - 在给定 SecureString 密码的情况下,从 PFX 文件保存和加载 CngKey 的最简单方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34344226/

相关文章:

java - 在另一台计算机上导出并重新导入 ECDSA 私钥后, key 会有所不同

c# - 寻找比 MD5 或 SHA256 更快的 C# 哈希

带有 SDK 工具的证书(makecert、pvk2pfx)

pfx - 不使用 OpenSSL 从 PFX 文件中提取证书

java - 如何制作具有动态 SSL 身份验证的 Soap 客户端?

c# - 如何像在 Eclipse (java) 中一样在 Visual Studio c# 中自动提取引用

C# 总是从基类调用基方法

c# - Linq to SQL 中的 DAO 工厂

c# - 使用 linq 查询作为 Microsoft 本地报告数据源 (WinForms)

node.js - 如何在 Node.js 中加密?