在 C# 中生成 X.509 证书密钥对和签名请求 (CSR)

发布于 2024-07-06 03:56:07 字数 60 浏览 6 评论 0原文

如何生成 X.509 公钥和私钥对以及要发送到 CA 以便在 C# 中进行签名的签名请求(CSR 文件)?

How do you generate a X.509 public and private key pair and a signing request (CSR file) to be sent to a CA for signing in C#?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

染火枫林 2024-07-13 03:56:07

如果您使用从 Liping Dai 的网站 获取的 IAsn1Node 类,则以下方法应该可以为您完成此操作:

    private static readonly Oid oidInstance = new Oid();

    private static void AddSubjectString(IAsn1Node parent, string oid, string value)
    {
        if (!string.IsNullOrEmpty(value))
        {
            parent.AddChild(AddString(new Asn1Node
            {
                Tag = Asn1Tag.SET | Asn1TagClasses.CONSTRUCTED
            },
                                      oid, value));
        }
    }

    private static Asn1Node AddString(Asn1Node parent, string name, string value)
    {
        var childNode = new Asn1Node
        {
            Tag = Asn1Tag.SEQUENCE | Asn1TagClasses.CONSTRUCTED
        };
        parent.AddChild(childNode);

        var nameNode = new Asn1Node
        {
            Tag = Asn1Tag.OBJECT_IDENTIFIER,
            Data = oidInstance.Encode(name)
        };
        childNode.AddChild(nameNode);

        var valueNode = new Asn1Node();
        if (value == null)
        {
            valueNode.Tag = Asn1Tag.TAG_NULL;
        }
        else
        {
            valueNode.Tag = Asn1Tag.PRINTABLE_STRING;
            valueNode.Data = Encoding.ASCII.GetBytes(value);
        }
        childNode.AddChild(valueNode);

        return parent;
    }

    public static void GenerateCsr(RSACryptoServiceProvider keyPair, Certificates.Subject subject, Stream output)
    {
        var rootNode = new Asn1Node
        {
            Tag = Asn1Tag.SEQUENCE | Asn1TagClasses.CONSTRUCTED
        };

        var topSequenceNode = new Asn1Node
        {
            Tag = Asn1Tag.SEQUENCE | Asn1TagClasses.CONSTRUCTED
        };
        rootNode.AddChild(topSequenceNode);

        var versionNode = new Asn1Node
        {
            Tag = Asn1Tag.INTEGER,
            Data = new byte[] { 0 }
        };
        topSequenceNode.AddChild(versionNode);

        var stringSequenceNode = new Asn1Node
        {
            Tag = Asn1Tag.SEQUENCE | Asn1TagClasses.CONSTRUCTED
        };
        topSequenceNode.AddChild(stringSequenceNode);

        AddSubjectString(stringSequenceNode, Oid.OID_COMMON_NAME, subject.CommonName);
        AddSubjectString(stringSequenceNode, Oid.OID_ORGANIZATIONAL_UNIT, subject.OrganisationalUnit);
        AddSubjectString(stringSequenceNode, Oid.OID_LOCALITY_NAME, subject.City);
        AddSubjectString(stringSequenceNode, Oid.OID_COUNTRY_NAME, subject.Country);
        AddSubjectString(stringSequenceNode, Oid.OID_PROVINCE_NAME, subject.Province);
        AddSubjectString(stringSequenceNode, Oid.OID_ORGANIZATION, subject.Organisation);
        AddSubjectString(stringSequenceNode, Oid.OID_EMAIL_ADDRESS, subject.EmailAddress);

        var rsaNode = new Asn1Node
        {
            Tag = Asn1Tag.SEQUENCE | Asn1TagClasses.CONSTRUCTED
        };
        topSequenceNode.AddChild(AddString(rsaNode, Oid.OID_RSA_ENCRYPTION, null));

        var publicKeyNode = new Asn1Node
        {
            Tag = Asn1Tag.BIT_STRING
        };
        rsaNode.AddChild(publicKeyNode);

        var publicKeySequenceNode = new Asn1Node
        {
            Tag = Asn1Tag.SEQUENCE | Asn1TagClasses.CONSTRUCTED
        };
        publicKeyNode.AddChild(publicKeySequenceNode);

        var publicKeyInfo = keyPair.ExportParameters(false);

        publicKeySequenceNode.AddChild(new Asn1Node
        {
            Tag = Asn1Tag.INTEGER,
            Data = publicKeyInfo.Modulus
        });
        publicKeySequenceNode.AddChild(new Asn1Node
        {
            Tag = Asn1Tag.INTEGER,
            Data = publicKeyInfo.Exponent
        });

        topSequenceNode.AddChild(new Asn1Node
        {
            Tag = Asn1TagClasses.CONTEXT_SPECIFIC | Asn1TagClasses.CONSTRUCTED
        });

        byte[] signature;
        using (var data = new MemoryStream(1024))
        {
            topSequenceNode.SaveData(data);
            signature = keyPair.SignData(data.GetBuffer(), 0, (int)data.Length, new SHA1CryptoServiceProvider());
        }

        AddString(rootNode, Oid.OID_SHA1_WITH_RSA, null);
        rootNode.AddChild(new Asn1Node
        {
            Tag = Asn1Tag.BIT_STRING,
            Data = signature
        });

        var csrOutput = new StreamWriter(output);

        csrOutput.WriteLine("-----BEGIN CERTIFICATE REQUEST-----");

        using (var data = new MemoryStream(1024))
        {
            rootNode.SaveData(data);
            var base64Data = Convert.ToBase64String(data.GetBuffer(), 0, (int)data.Length,
                                                    Base64FormattingOptions.InsertLineBreaks);
            csrOutput.WriteLine(base64Data);
        }

        csrOutput.WriteLine("-----END CERTIFICATE REQUEST-----");
        csrOutput.Flush();
    }

感谢 Theodor 来拯救我们并为我们写了它。

If you use the IAsn1Node class that you can get from Liping Dai's website the following methods should do it for you:

    private static readonly Oid oidInstance = new Oid();

    private static void AddSubjectString(IAsn1Node parent, string oid, string value)
    {
        if (!string.IsNullOrEmpty(value))
        {
            parent.AddChild(AddString(new Asn1Node
            {
                Tag = Asn1Tag.SET | Asn1TagClasses.CONSTRUCTED
            },
                                      oid, value));
        }
    }

    private static Asn1Node AddString(Asn1Node parent, string name, string value)
    {
        var childNode = new Asn1Node
        {
            Tag = Asn1Tag.SEQUENCE | Asn1TagClasses.CONSTRUCTED
        };
        parent.AddChild(childNode);

        var nameNode = new Asn1Node
        {
            Tag = Asn1Tag.OBJECT_IDENTIFIER,
            Data = oidInstance.Encode(name)
        };
        childNode.AddChild(nameNode);

        var valueNode = new Asn1Node();
        if (value == null)
        {
            valueNode.Tag = Asn1Tag.TAG_NULL;
        }
        else
        {
            valueNode.Tag = Asn1Tag.PRINTABLE_STRING;
            valueNode.Data = Encoding.ASCII.GetBytes(value);
        }
        childNode.AddChild(valueNode);

        return parent;
    }

    public static void GenerateCsr(RSACryptoServiceProvider keyPair, Certificates.Subject subject, Stream output)
    {
        var rootNode = new Asn1Node
        {
            Tag = Asn1Tag.SEQUENCE | Asn1TagClasses.CONSTRUCTED
        };

        var topSequenceNode = new Asn1Node
        {
            Tag = Asn1Tag.SEQUENCE | Asn1TagClasses.CONSTRUCTED
        };
        rootNode.AddChild(topSequenceNode);

        var versionNode = new Asn1Node
        {
            Tag = Asn1Tag.INTEGER,
            Data = new byte[] { 0 }
        };
        topSequenceNode.AddChild(versionNode);

        var stringSequenceNode = new Asn1Node
        {
            Tag = Asn1Tag.SEQUENCE | Asn1TagClasses.CONSTRUCTED
        };
        topSequenceNode.AddChild(stringSequenceNode);

        AddSubjectString(stringSequenceNode, Oid.OID_COMMON_NAME, subject.CommonName);
        AddSubjectString(stringSequenceNode, Oid.OID_ORGANIZATIONAL_UNIT, subject.OrganisationalUnit);
        AddSubjectString(stringSequenceNode, Oid.OID_LOCALITY_NAME, subject.City);
        AddSubjectString(stringSequenceNode, Oid.OID_COUNTRY_NAME, subject.Country);
        AddSubjectString(stringSequenceNode, Oid.OID_PROVINCE_NAME, subject.Province);
        AddSubjectString(stringSequenceNode, Oid.OID_ORGANIZATION, subject.Organisation);
        AddSubjectString(stringSequenceNode, Oid.OID_EMAIL_ADDRESS, subject.EmailAddress);

        var rsaNode = new Asn1Node
        {
            Tag = Asn1Tag.SEQUENCE | Asn1TagClasses.CONSTRUCTED
        };
        topSequenceNode.AddChild(AddString(rsaNode, Oid.OID_RSA_ENCRYPTION, null));

        var publicKeyNode = new Asn1Node
        {
            Tag = Asn1Tag.BIT_STRING
        };
        rsaNode.AddChild(publicKeyNode);

        var publicKeySequenceNode = new Asn1Node
        {
            Tag = Asn1Tag.SEQUENCE | Asn1TagClasses.CONSTRUCTED
        };
        publicKeyNode.AddChild(publicKeySequenceNode);

        var publicKeyInfo = keyPair.ExportParameters(false);

        publicKeySequenceNode.AddChild(new Asn1Node
        {
            Tag = Asn1Tag.INTEGER,
            Data = publicKeyInfo.Modulus
        });
        publicKeySequenceNode.AddChild(new Asn1Node
        {
            Tag = Asn1Tag.INTEGER,
            Data = publicKeyInfo.Exponent
        });

        topSequenceNode.AddChild(new Asn1Node
        {
            Tag = Asn1TagClasses.CONTEXT_SPECIFIC | Asn1TagClasses.CONSTRUCTED
        });

        byte[] signature;
        using (var data = new MemoryStream(1024))
        {
            topSequenceNode.SaveData(data);
            signature = keyPair.SignData(data.GetBuffer(), 0, (int)data.Length, new SHA1CryptoServiceProvider());
        }

        AddString(rootNode, Oid.OID_SHA1_WITH_RSA, null);
        rootNode.AddChild(new Asn1Node
        {
            Tag = Asn1Tag.BIT_STRING,
            Data = signature
        });

        var csrOutput = new StreamWriter(output);

        csrOutput.WriteLine("-----BEGIN CERTIFICATE REQUEST-----");

        using (var data = new MemoryStream(1024))
        {
            rootNode.SaveData(data);
            var base64Data = Convert.ToBase64String(data.GetBuffer(), 0, (int)data.Length,
                                                    Base64FormattingOptions.InsertLineBreaks);
            csrOutput.WriteLine(base64Data);
        }

        csrOutput.WriteLine("-----END CERTIFICATE REQUEST-----");
        csrOutput.Flush();
    }

Thanks to Theodor who came to the rescue and wrote it for us.

因为看清所以看轻 2024-07-13 03:56:07

生成 RSA 密钥对很容易:

// Generate a 2048 bit RSA keypair
RSA keypair = new RSACryptoServiceProvider(2048);

不幸的是 .NET 不支持生成证书请求。 您最好的选择可能是与 COM 组件交互 CEnroll 。 您应该使用 CreatePKCS10 方法。

Generating a RSA key-pair is easy:

// Generate a 2048 bit RSA keypair
RSA keypair = new RSACryptoServiceProvider(2048);

Unfortunately .NET has no support for generating certificate-requests. Your best bet is probably to interface with the COM-component CEnroll. You should use the CreatePKCS10-method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文