使用 C# 从 CA 证书为设备创建 X509 证书

Posted

技术标签:

【中文标题】使用 C# 从 CA 证书为设备创建 X509 证书【英文标题】:Create X509 Certificate for Device from a CA certificate using C# 【发布时间】:2021-12-26 11:53:54 【问题描述】:

我声明我不是证书主题的专家,我可能对证书链签名不太了解。

我们的客户将向我们发送一个作为中间证书的 CA 证书,我们必须创建将存储在我们的设备中的设备证书,以便与将使用中间证书注册组的设备配置服务连接。

是否可以仅使用 C# 从 CA 证书创建设备证书? 我们想将 CA 证书(中间证书)添加到我们的设备,并使用用 C# 编写的软件为设备创建证书? (如果需要,我们也可以使用其他类型的脚本或openssl)。可以吗?

我做了一些测试。我使用此链接上的脚本创建了根证书和中间证书 https://docs.microsoft.com/it-it/azure/iot-hub/tutorial-x509-scripts 然后,使用中间证书,我尝试了这个

    X509Certificate2 certificate = new X509Certificate2("myIntermediateCA.pem");
    
    ECDsa ecd = ECDsa.Create();
    CertificateRequest req = new CertificateRequest("CN=myDevice",   
    ecd,
    HashAlgorithmName.SHA256);
    req.CertificateExtensions.Add(new X509BasicConstraintsExtension(false, false, 0, false));
    req.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.KeyEncipherment, 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));
    X509Certificate2 cert2 = req.Create(
                        certificate,
                        DateTimeOffset.UtcNow.AddDays(-1),
                        DateTimeOffset.UtcNow.AddDays(2),
                        new byte[]  1, 2, 3, 4 );
   byte[] exported = cert2.Export(X509ContentType.Pfx, "pass12345678");
   string certificatePfxPath = "myDevice.pfx";
   File.WriteAllBytes(certificatePfxPath, exported);

但它不起作用。如果我使用 myDevice.pfx 连接到我创建了一个使用中间证书的组的设备配置服务,我有一个错误,表明该设备未经授权。 (使用此代码创建的设备证书似乎没有私钥。 但它必须有还是没有?)

谢谢!

【问题讨论】:

【参考方案1】:

我们的客户将向我们发送作为中间证书的 CA 证书,我们必须创建将存储在我们的设备中的设备证书,以便与设备配置服务连接,在该服务中,将使用中间证书注册一个组。

有一个基本问题。客户只向您发送 CA 证书的公共部分。您不能使用此证书签署其他证书,因为签署过程需要与 CA 证书关联的私钥,而这很可能不是客户提供的。

解决这个问题有两种选择:

    在您的环境中安装由客户 CA 内部签名的从属 CA。也就是说,您安装 CA,生成 CA 请求,提交给客户进行签名并接收您安装到 CA 的签名 CA 证书。然后使用您的本地 CA 签署设备证书。 要求客户提供接受 PKCS#10 请求作为输入并返回签名 x.509 证书的证书签名 API(或其他流程)。

选项 1 在大多数情况下都有问题,因为这允许您颁发客户信任的任意证书。这会引起您和客户之间的隐私和安全问题,因为您可以轻松欺骗客户的 PKI 及其安全性。

每次您需要签署证书时,选项 2 都需要与客户环境/API 进行交互。另一方面,如果客户发现请求未经授权或不符合合规/政策规则,则可以审查每个请求并拒绝该请求。

是否可以仅使用 C# 从 CA 证书创建设备证书?

在任何情况下,您都不应这样做,而应使用专门的 CA 软件。例如,Microsoft ADCS、PKI Prime EJBCA、您选择的其他 CA 供应商/软件(也不要使用纯 OpenSSL)。

为什么需要使用专门的 CA 软件?这是因为,请求签名只是 CA 操作的一部分。其他操作包括:适当的扩展生成、CRL 和 CA 证书分发点(CDP 和 AIA 扩展)定义和维护、CA 数据库维护、撤销功能等。大多数这些任务都在RFC 5280 中定义。不要推出自己的加密/CA,因为即使对于有经验的人来说,这也不是一件容易的事。

【讨论】:

感谢您的回答!我在看这个docs.microsoft.com/en-us/azure/iot-hub/iot-hub-x509ca-concept 在链中,我们是Factory X。我们是设备(硬件和软件)的制造商,我们希望以最简单和最快的方式将证书上传到设备上以进行生产过程。因此,公司不仅必须为我们提供中间证书,还必须提供一些环境/API,以便能够为设备创建证书。对吗? 如果要求设备证书必须由其 CA 签名(链到其根),那么您需要 API 或从属 CA 证书,其私钥由客户 CA 颁发。

以上是关于使用 C# 从 CA 证书为设备创建 X509 证书的主要内容,如果未能解决你的问题,请参考以下文章

使用 node.js 验证带有 CA 证书的 X509 证书

如何创建一个自签名的SSL证书(X509)

CA签名X509证书包含X509v3扩展名“主题备用名称”两次

x509的简介

在 iOS 设备上快速创建新的 X509 证书

iOS适配HTTPS,创建一个自签名的SSL证书(x509)具体步骤