首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C# -基于byte[]中的给定颁发者证书生成X509证书

C# -基于byte[]中的给定颁发者证书生成X509证书
EN

Stack Overflow用户
提问于 2021-09-19 14:54:58
回答 1查看 71关注 0票数 0

我想从C#代码创建iothub设备证书。根CA作为.pfx存储在keyvault中,作为字符串获取,然后从base64转换,以便获得证书字节,因为它是存储在keyvault:Azure Key Vault Certificates does not have the Private Key when retrieved via IKeyVaultClient.GetCertificateAsync中的证书所必需的

我想要编写一个函数,该函数将接受这些字节,以及一个主题名称(用于叶证书),并将创建一个x509证书(具有公钥和私钥),该证书将以颁发者作为根。

以下是我到目前为止所概述的内容:

代码语言:javascript
运行
复制
public static X509Certificate2 GenerateCertificateBasedOnIssuer(string subjectName, byte[] issuerByteCert)
        {
            var issuerCertificate = new X509Certificate2(issuerByteCert);

            RSA keyProvider = issuerCertificate.GetRSAPrivateKey();

            CertificateRequest certificateRequest = new CertificateRequest($"CN={subjectName}", keyProvider, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);

            CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
            SecureRandom random = new SecureRandom(randomGenerator);
            BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);

            var publicOnlyDeviceCertificate = certificateRequest.Create(issuerCertificate, issuerCertificate.NotBefore, issuerCertificate.NotAfter, serialNumber.ToByteArray());

            return publicOnlyDeviceCertificate; // oh no ! :(

        }

这个解决方案的问题是创建的证书只包含一个公钥。

我找到了另一个解决方案,似乎可以使用BouncyCastleX509V3CertificateGenerator解决另一个堆栈溢出问题:Generate a self-signed certificate on the fly

这个解决方案的问题是我无法将rootCA证书的私钥转换为AsymmetricKeyParameter ( X509V3CertificateGenerator.Generate方法的第一个参数)。我尝试使用以下解决方案将颁发者的密钥转换为AsymmetricKeyParameterconvert PEM encoded RSA public key to AsymmetricKeyParameter,但我得到了一个无效操作异常。

我想知道我是否在正确的道路上(就理解而言),以及是否有一种方法可以基于我目前已有的代码生成具有私钥(和公钥)的证书。

更新:我已经能够通过硬编码密钥将私钥转换为AsymmetricKeyParameter,如下所示:

代码语言:javascript
运行
复制
 string testKey = @"-----BEGIN PRIVATE KEY-----
<THE KEY>
-----END PRIVATE KEY-----
";
 var stringReader = new StringReader(testKey);
 var pemReader = new PemReader(stringReader);
 var pemObject = pemReader.ReadObject(); 
 var keyParam = ((AsymmetricKeyParameter)pemObject);

Azure密钥库以pfx格式存储证书。我正在考虑将私钥存储为秘密字符串。现在,我将继续使用硬编码的密钥进行测试,直到我得到一个有效的解决方案。

我现在正在使用BouncyCastle进行测试,如果它有效的话,我会带着一个有效的解决方案回来的!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-19 17:41:40

您传递给CertificateRequest的密钥将用作证书中的公钥...所以你想要传递一个新的密钥,而不是发行者的密钥。

然后,一旦您有了主题密钥,您就可以在最后使用CopyWithPrivateKey将它们粘合在一起。

代码语言:javascript
运行
复制
public static X509Certificate2 GenerateCertificateBasedOnIssuer(string subjectName, byte[] issuerByteCert)
{
    using (var issuerCertificate = new X509Certificate2(issuerByteCert))
    using (RSA subjectKey = RSA.Create(2048))
    {
        CertificateRequest certificateRequest = new CertificateRequest($"CN={subjectName}", subjectKey, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);

        CryptoApiRandomGenerator randomGenerator = new CryptoApiRandomGenerator();
        SecureRandom random = new SecureRandom(randomGenerator);
        BigInteger serialNumber = BigIntegers.CreateRandomInRange(BigInteger.One, BigInteger.ValueOf(Int64.MaxValue), random);

        var publicOnlyDeviceCertificate = certificateRequest.Create(issuerCertificate, issuerCertificate.NotBefore, issuerCertificate.NotAfter, serialNumber.ToByteArray());

        using (publicOnlyDeviceCertificate)
        {
            return publicOnlyDeviceCertificate.CopyWithPrivateKey(subjectKey);
        }
    }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69244382

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档