使用纯 .net 框架生成和签署证书请求

时间:2023-03-27
本文介绍了使用纯 .net 框架生成和签署证书请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

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

I am trying to use pure .net code to create a certificate request and create a certificate from the certificate request against an existing CA certificate I have available (either in the Windows Certificate store or as a separate file).

我知道我有类 X509CertificateX509Certificate2 可用于加载证书并访问其信息,但我在 System.Security.Cryptography 命名空间,可用于创建证书请求或签署此类证书请求以创建新的签名证书.

I know that I have the classes X509Certificate and X509Certificate2 available to load certificates and get access to their information, but I don't see any classes or functionality within the System.Security.Cryptography namespace that could be used to create a certificate request or to sign such a certificate request to create a new signed certificate.

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

And that although the documentation on the System.Security.Cryptography.Pkcs namespace says:

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

The System.Security.Cryptography.Pkcs namespace provides programming elements for Public Key Cryptography Standards (PKCS), including methods for signing data, exchanging keys, requesting certificates, public key encryption and decryption, and other security functions.

那么,我如何创建证书请求并满足该请求以仅使用来自 System.Security.Cryptography 的纯 .net 类来创建新的 X509 证书?

So, how can I create a certificate request and fulfill that request to create a new X509 certificate using only pure .net classes from System.Security.Cryptography?

注意:

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

推荐答案

简答:你可以从 .NET Framework 4.7.2 开始.

Short answer: You can starting in .NET Framework 4.7.2.

此功能最初以 CertificateRequest 类,可以构建 PKCS#10 证书签名请求或 X.509(自签名或链式)公钥证书.

This functionality was originally added to .NET Core 2.0 in the form of the CertificateRequest class, which can build a PKCS#10 certification signing request or an X.509 (self-signed or chained) public key certificate.

该功能的类在 .NET Framework 4.7.2 中可用.

The classes for that feature were made available in .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 的情况下实现您的目标,您需要阅读并理解以下文档:

Longer answer if you're stuck on older versions: To accomplish your goal without adding any new P/Invokes, you would need to read and understand the following documents:

  • 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.
  • ITU-T X.680-201508, the ASN.1 language
  • IETF RFC 5280 or ITU-T X.509, the documents that explain the fields in X.509 certificates.
  • IETF RFC 2986, explains the PKCS#10 certification signing request
  • ITU-T X.690, explains the BER encoding family for ASN.1 (including DER) which tells you how to read and write bytes to achieve the semantic meaning from X.509 / PKCS#10.

然后您可以编写一个 DER 写入器/读取器,然后只发出您想要的字节.

And then you could write a DER writer/reader, and just emit the bytes for what you want.

这篇关于使用纯 .net 框架生成和签署证书请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:C# 将私有/公共 RSA 密钥从 RSACryptoServiceProvider 导出到 PEM 字符串 下一篇:C# RSA 加密/解密与传输

相关文章