生成CrypoAPI(CAPI)私钥

4
我正在尝试使用IXmlEncryptor实现加密存储。具体地说,使用CertificateEncryptor。(这是ASP.NET Core中IXmlRepository系统的一部分,用于共享解密cookie和一般key management)。
文档页面讨论了使用X.509证书进行此操作的方法。
它指出,“仅支持带有CAPI私钥的证书”。
Google搜索显示,CAPI表示Microsoft CryptAPI。但我找不到更多信息,而我能找到的似乎与C++相关。

当我问我的“证书专家”什么是“CAPI私钥”时,他基本上告诉了我这个:

Microsoft生成的PFX文件转换为x509需要密码。那可能是我能想到的唯一事情。

那是不是同一件事呢?

如果不是,如何创建具有CAPI私钥的X.509证书?

注意:X.509证书是文档页面上列出的选项中唯一适用于Linux机器(容器)的选项。这就是为什么我不考虑任何其他(可能更简单)的选项的原因。

2个回答

7
您的"证书专家"是错误的。
微软有两个加密系统版本:传统CryptAPI(简称CryptoAPI或CAPI)和密码学下一代(CNG,CAPI2)。
CrytpoAPI是在Windows 2000中发明的。传统CryptoAPI已经过时,不支持ECC,SHA2:只支持RSA/遗留DSA(长达1k的密钥),DES/3DES,RCx,没有内置AES。密钥存储在传统的密码服务提供程序(CSP)中。但是,在Windows Vista+中,添加了具有SHA2和AES的传统CSP,以帮助旧应用程序使用它们而不需要更改太多代码。
CNG最初于2007年在Windows Vista / Windows Server 2008中引入,并且真的是好东西:它非常可扩展,具有NSA Suite B密码学的本地支持(ECC非对称密钥,SHA2算法组),密钥隔离,统一的一组BCrypt函数等。大多数仅限于CNG的API包括NCrypt,BCrypt,CNG,NG后缀/前缀在其名称中,以明确表示它是CNG API。在CNG中,密钥存储在重新设计的CSP中,称为密钥存储提供程序(KSP),以将其与传统CSP区分开来,因为它们不同(尽管存在从KSP访问CSP的单向桥梁,但不是反之亦然)。
然而,.NET在采用CNG方面一直在努力,并且只有在.NET 4.7中才使其可以使用(尽管实现之前已存在,但具有已知限制),并且仅当第三方应用程序明确添加对其的支持时,CNG才受到支持,因为CNG使用不同的API,而.NET Framework升级并不使应用程序具备CNG功能。
这是关于CAPI和CAPI2之间的区别的一点理论知识。
您的文档要求使用传统CSP存储私钥的证书。在Windows中创建时,如果使用以下提供程序之一,则使用传统CSP:
Microsoft Base Cryptographic Provider v1.0
Microsoft Base DSS and Diffie-Hellman Cryptographic Provider
Microsoft Base DSS Cryptographic Provider
Microsoft Base Smart Card Crypto Provider
Microsoft DH SChannel Cryptographic Provider
Microsoft Enhanced Cryptographic Provider v1.0
Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider
Microsoft Enhanced RSA and AES Cryptographic Provider
Microsoft RSA SChannel Cryptographic Provider <- this is preferred for legacy CSPs
Microsoft Strong Cryptographic Provider

您可以在Windows上创建证书(密钥对)时指定任何一个选项。例如,使用默认的CNG KSP的New-SelfSignedCertificate PowerShell cmdlet或certreq.exe工具生成请求以由外部CA签名。此部分取决于您用于创建证书/证书请求的工具。

谢谢您的回答!这些细节很棒!我觉得很惊讶的是,(更新的).Net Core IXmlEncryptor只支持Windows 2000时代的解决方案!我非常困惑他们在将.Net重写为.Net Core时为什么要这样做。 - Vaccano
1
有趣。这些API非常新(仅限.NET Core)。也许,它们对旧的东西有深层次的依赖,我不知道。但这是另一个问题。 - Crypt32
1
在托管世界和本地世界中,CAPI/CNG的选择都是明确的。在两个System.Security.Cryptography.RSA实现之间,RSACryptoServiceProvider类基于传统的CryptoAPI工作,而RSAKey则由CNG支持。 - Seva Alekseyev

1

这是一个使用Microsoft RSA SChannel Cryptographic Provider生成证书的工作示例,正如Crypt32的答案所建议的那样。密钥存储在数据库中。已在Windows 10和Ubuntu 18.04.5 LTS上进行测试。

使用ASP.NET Core 3.1。在Windows 10上开发,在Ubuntu 18.04.5上托管。

使用管理员权限的PowerShell

New-SelfSignedCertificate -provider "Microsoft RSA SChannel Cryptographic Provider" -FriendlyName "site_key" -KeyAlgorithm RSA -KeyLength 2048 -NotAfter (Get-Date).AddYears(30) -subject "site_key" -KeyExportPolicy "Exportable"

   PSParentPath: Microsoft.PowerShell.Security\Certificate::LocalMachine\MY

Thumbprint                                Subject
----------                                -------
{thumbprint}                              CN=site_key

$mypwd = ConvertTo-SecureString -String "<secret>" -Force -AsPlainText Get-ChildItem -Path cert:\localMachine\my\{thumbprint} | Export-PfxCertificate -FilePath C:\site.pfx -Password $mypwd

StartUp.ConfigureServices() 中的 services.AddDbContext() 后面。

// using System.IO;
var pfxFile = Path.GetFullPath(Path.Combine("folder1", "site.pfx"));

// using System.Security.Cryptography.X509Certificates;
services.AddDataProtection()
        .PersistKeysToDbContext<MyKeysContext>();
        .ProtectKeysWithCertificate(new X509Certificate2(pfxFile, "<secret>"));

可能需要删除 DataProtectionKeys 表的内容并重新启动 Web 应用程序,以将加密密钥存储在该表中。

Microsoft 有关使用证书保护密钥的文档

Microsoft 有关使用 X509Certificate2 证书保护密钥的文档

New-SelfSignedCertificate 参考

Export-PfxCertificate 参考


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接