c# - 使用纯.net Framework生成和签署证书请求



cryptography system.security (1)

我正在尝试使用纯.net代码创建证书请求,并根据我可用的现有CA证书(在Windows证书存储区中或作为单独的文件)从证书请求创建证书。

我知道我有类 X509CertificateX509Certificate2 可用于加载证书并获取对其信息的访问权限,但我没有看到 System.Security.Cryptography 命名空间中可用于创建证书请求的任何类或功能。签署此类证书请求以创建新的签名证书。

虽然 System.Security.Cryptography.Pkcs 命名空间上 文档 说:

System.Security.Cryptography.Pkcs命名空间提供公钥加密标准(PKCS)的编程元素,包括签名数据,交换密钥, 请求证书 ,公钥加密和解密以及其他安全功能的方法。

那么,如何使用 System.Security.Cryptography 纯.net类创建证书请求并签署该请求以创建新的X509证书?

注意:

  • 我不想使用像openssl或MakeCert这样的外部可执行文件
  • 我不想使用BouncyCastle
  • 我不想使用Windows 证书注册API
  • 我不想使用本机Win32 API函数

简短回答:您可以从.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的情况下实现目标,您需要阅读并理解以下文档:

  • ITU-T X.680 -201508,ASN.1语言
  • IETF RFC 5280 或ITU-T X.509 ,解释X.509证书中字段的文档。
  • IETF RFC 2986 解释了PKCS#10认证签名请求
  • ITU-T X.690 解释了ASN.1(包括DER)的BER编码系列,它告诉您如何读取和写入字节以实现X.509 / PKCS#10的语义含义。

然后你可以写一个DER编写器/阅读器,然后只发出你想要的字节。





system.security