我有一个用.NET Core 2.1编写的控制台应用程序,并且具有两个功能-
一种:加载一个证书链(证书,中间证书和根证书)以及一个私钥,它们位于从.p7b文件和.key文件创建的一个.p12文件中。使用X509Certificate2
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中,它仅加载签名证书。我在这里或互联网的其余部分找不到任何相关的内容,所以我问是否有人有任何线索,我的问题在哪里?
关于, 朱利安
答案 0 :(得分:0)
问题是Linux机器不信任中间证书和根证书。正如@ Crypt32在问题下方的第一条评论中所建议的那样,将它们添加到受信任的存储区,解决了该问题。谢谢!