gpt4 book ai didi

c# - 使用 .NET 中的证书文件中的根 CA 进行数字签名

转载 作者:行者123 更新时间:2023-11-30 21:53:22 30 4
gpt4 key购买 nike

我必须使用证书和私钥对 C# 中的一些数据进行数字签名。我使用的证书有一个自定义根 CA 以及一个自定义中间 CA。

我可以使用这样的代码来毫无问题地进行签名,如果根和中间 CA 安装到 Windows 证书存储中:

var content = new ContentInfo(manifest);
var cms = new SignedCms(content, true);
var signer = new CmsSigner(SubjectIdentifierType.SubjectKeyIdentifier, myCertificate);

signer.SignedAttributes.Add(new Pkcs9SigningTime(DateTime.Now));
cms.ComputeSignature(signer);

return cms.Encode();

不幸的是,我无法将根 CA 和中间 CA 安装到服务器的证书存储中(我使用的是 Azure Web 应用程序)。如果它们存储在磁盘上,我正在尝试找到一种使用根和中间 CA 证书进行签名的方法。我想我可以在调用 cms.Encode() 之前做这样的事情:

// add CAs from disk
var intermediateCACertificate = new X509Certificate2(@"pathToIntermediateCertificate.cer");
signer.Certificates.Add(intermediateCACertificate);

var rootCACertificate = new X509Certificate2(@"pathToRootCertificate.cer");
signer.Certificates.Add(rootCACertificate);

但是,当我执行此操作时,我得到一个 CryptographicException 抛出 “无法为受信任的根机构构建证书链。”

是否可以使用非标准 CA 进行数字签名而不将它们安装到 Windows 证书存储中?

最佳答案

这是可能的。

基本上,从 SignedCms 类返回的 BLOB 除了签名本身之外,还能够包含任意数量的任意证书。通常这样做是为了至少包括消息签名所用的证书以及可能的任何其他中间证书,以便接收实体可以验证签名直到它信任的根证书。

当您调用上面的 signer.Certificates.Add() 调用时,您正在添加要在输出签名 BLOB 中编码的证书。但是,将证书添加到此集合中并不意味着对它们有任何形式的“信任”。

您遇到的问题是,默认情况下 .NET SignedCms 类试图通过自动包含典型情况下包含的证书来帮助您。默认情况下,它包括链中除根证书之外的所有证书。它通过尝试使用它在服务器的证书存储中找到的证书构建一个链来实现这一点,正如您所注意到的,当未安装根/中间 CA 的证书时,该链会失败。

证书链构建由 CmsSigner.IncludeOption 属性控制。默认值为 X509IncludeOption.ExcludeRoot。此值和 X509IncludeOption.WholeChain 都将在您的系统上失败,因为该类将无法基于证书存储中的内容构建链。

您可能想要执行的操作如下:

signer.IncludeOption = X509IncludeOption.EndCertOnly;
signer.Certificates.Add(intermediateCACertificate);
signer.Certificates.Add(rootCACertificate);

这将包括您要签名的证书(当您指定 EndCertOnly 时包括在内)以及显式添加的中间证书和根证书。 SignedCms 不会尝试构建证书链,因为它只需要包含一个已经提供的证书,因此不会抛出任何异常。

顺便说一句,你可以像这样得到与上面相同的结果:

signer.IncludeOption = X509IncludeOption.None;
signer.Certificates.Add(myCertificate);
signer.Certificates.Add(intermediateCACertificate);
signer.Certificates.Add(rootCACertificate);

在这种情况下,签名证书不会自动包含在内,但下一行明确地将其添加到集合中。

根据您的接收者信任的 CA,您可能不需要像上面那样将所有证书都包含在链中,并且您可以只包含签名证书。但是,我建议至少手动包括但不包括根目录,因为这是 .NET 默认行为。事实上,包含整个链也没有真正的危害,但出于所有意图和目的,接收方应该已经信任根 CA,否则 PKI 的整个概念就会崩溃。

关于c# - 使用 .NET 中的证书文件中的根 CA 进行数字签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33904167/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com