我正在尝试使用纯.net代码创建证书请求,并根据我可用的现有CA证书(在Windows证书存储区中或作为单独的文件)从证书请求创建证书。
我知道我可以使用类X509Certificate
和X509Certificate2
来加载证书并获取对其信息的访问权限,但我在System.Security.Cryptography
命名空间中看不到任何类或功能可用于创建证书请求或签署此类证书请求以创建新的签名证书。
虽然documentation on the System.Security.Cryptography.Pkcs
namespace说:
System.Security.Cryptography.Pkcs命名空间提供编程 公钥加密标准(PKCS)的要素,包括 签名数据,交换密钥,请求证书的方法, 公钥加密和解密,以及其他安全功能。
那么,如何使用System.Security.Cryptography
中的纯.net类创建证书请求并签署该请求以创建新的X509证书?
注意:
答案 0 :(得分:31)
简短回答:您可以从.NET Framework 4.7.2开始。
此功能最初以CertificateRequest类的形式添加到.NET Core 2.0,可以构建PKCS#10认证签名请求或X.509(自签名或链接)公钥证书
该功能的类在.NET Framework 4.7.2中提供。
using (RSA parent = RSA.Create(4096))
using (RSA rsa = RSA.Create(2048))
{
CertificateRequest parentReq = new CertificateRequest(
"CN=Experimental Issuing Authority",
parent,
HashAlgorithmName.SHA256,
RSASignaturePadding.Pkcs1);
parentReq.CertificateExtensions.Add(
new X509BasicConstraintsExtension(true, false, 0, true));
parentReq.CertificateExtensions.Add(
new X509SubjectKeyIdentifierExtension(parentReq.PublicKey, false));
using (X509Certificate2 parentCert = parentReq.CreateSelfSigned(
DateTimeOffset.UtcNow.AddDays(-45),
DateTimeOffset.UtcNow.AddDays(365)))
{
CertificateRequest req = new CertificateRequest(
"CN=Valid-Looking Timestamp Authority",
rsa,
HashAlgorithmName.SHA256,
RSASignaturePadding.Pkcs1);
req.CertificateExtensions.Add(
new X509BasicConstraintsExtension(false, false, 0, false));
req.CertificateExtensions.Add(
new X509KeyUsageExtension(
X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.NonRepudiation,
false));
req.CertificateExtensions.Add(
new X509EnhancedKeyUsageExtension(
new OidCollection
{
new Oid("1.3.6.1.5.5.7.3.8")
},
true));
req.CertificateExtensions.Add(
new X509SubjectKeyIdentifierExtension(req.PublicKey, false));
using (X509Certificate2 cert = req.Create(
parentCert,
DateTimeOffset.UtcNow.AddDays(-1),
DateTimeOffset.UtcNow.AddDays(90),
new byte[] { 1, 2, 3, 4 }))
{
// Do something with these certs, like export them to PFX,
// or add them to an X509Store, or whatever.
}
}
}
如果您坚持使用旧版本,则需要更长时间的答案:要在不添加任何新P / Invokes的情况下实现目标,您需要阅读并理解以下文档:
然后你可以写一个DER编写器/阅读器,然后只为你想要的东西发出字节。