X509Certificate2 在 widows 中不同,在 .NET Core 应用程序中 linux

X509Certificate2 different in widows and linux in .NET Core Application

我有一个用 .NET Core 2.1 编写的控制台应用程序,它有两个功能 - 一:加载证书链(证书、中间证书和根证书)以及私钥,它们位于一个由 .p7b 文件和 .key 文件创建的 .p12 文件中。这是在 X509Certificate2 class 中加载的,使用 ctor(string filename, string password)

我的设置在 Windows 上运行良好,但是当我在 Linux 环境 (debian 9) 中部署应用程序时,当我尝试对消息签名时,出现错误: A certificate chain could not be built to a trusted root authority. 这是加载证书的代码:

public CertificateManager(IOptions<CertificateSettings> options)
{
   var settings = options.Value;
   _filePath = settings.Path;
   _password = settings.Password;
   Certificate = new X509Certificate2(_filePath, _password);
}

xml 签名代码如下:

public string SignMessage(XmlNode message)
    {
        
        var signed = new SignedXml((XmlElement)message)
        {
            SigningKey = _certificateManager.Certificate.PrivateKey,
        };
        var referenceID = message.Attributes[PAResDescr.PAResID].Value;

        signed.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA1Url;

        var reference = new Reference { Uri = $"#{referenceID}" };
        reference.DigestMethod = SignedXml.XmlDsigSHA1Url;
        // Add the reference to the SignedXml object.
        signed.AddReference(reference);


        var keyInfo = new KeyInfo();
        var keyInfoData = new KeyInfoX509Data(_certificateManager.Certificate, X509IncludeOption.WholeChain);
        keyInfo.AddClause(keyInfoData);


        signed.KeyInfo = keyInfo;

        signed.ComputeSignature();

        return signed.GetXml().OuterXml;
    }

正如我所提到的,当我在 Windows 机器上 运行 时,这段代码工作正常,但是当我在 Linux (Debian 9) 上 运行 时,我得到提到的错误,这是整个堆栈跟踪:

at System.Security.Cryptography.Xml.KeyInfoX509Data..ctor(X509Certificate cert, X509IncludeOption includeOption)
at Payment.Service.Cryptography.LocalCertificateSigner.SignMessage(XmlNode message) in /home/juls/Projects/ACS/Payment.Service/Cryptography/LocalCertificateSigner.cs:line 44

有趣的是,当我 运行 这个没有 X509IncludeOption.WholeChain 构造函数参数时,错误消失了,但签名中只包含签名证书,而不是整个链。我的想法是,当证书加载时,在 windows 中加载整个链,但在 linux 中它只加载签名证书。我在这里或互联网的其余部分找不到任何相关内容,所以我想问问是否有人有任何线索,我的问题是什么?

此致, 朱利安

问题是 Linux 机器不信任中间证书和根证书。正如 @Crypt32 在问题下方的第一条评论中所建议的那样,将它们添加到受信任的商店,解决了问题。谢谢!