我正在编写处理证书的 C# 代码。我有一个以自签名根终止的证书链。在 Windows 上,我的代码运行良好,但在 Linux 上却失败了。我得到一个 X509ChainStatus 对象,其中包含状态 X509ChainStatusFlags.PartialChain 和状态信息 无法获取本地颁发者证书。
我的代码如下所示:
X509Certificate2Collection collection = GetCertificateCollectionFromResource(X509KeyStorageFlags.EphemeralKeySet);
var leaf = collection[0];
var parents = new[] { collection[1], collection[2] };
var chain = CreateChain(parents);
var valid = chain.Build(leaf);
if (!valid)
throw new Exception("Chain.Build returned false");
// We expect the root to be untrusted. It is a self-signed certificate. So the UntrustedRoot flag is harmless.
var illegalFlags = chain.ChainStatus.Where(f => f.Status != X509ChainStatusFlags.UntrustedRoot).ToList();
if (illegalFlags.Any())
{
var firstIllegalFlag = illegalFlags.First();
throw new Exception($"Illegal status flag found: {firstIllegalFlag.Status} ({firstIllegalFlag.StatusInformation})");
}
else
{
Console.WriteLine("Certificate collection is valid!");
}
我这里有一个完整的工作示例(仅包含所有证书的公共部分):https://github.com/CAP-3Shape/CertificateValidatorSample
当我使用
dotnet run
在 Windows 上运行示例时,它可以工作。当我在 Linux 上运行它时,我得到这个:
未处理的异常。 System.Exception:发现非法状态标志:PartialChain(无法获取本地颁发者证书) 在 /home/devops/actions-runner/work/Raven.KeyManagementService/Raven.KeyManagementService/CertificateValidatorSample/Program.cs 中的 ClausAppel.CertificateValidatorSample.Program.InstanceMain() 处:第 30 行 在 /home/devops/actions-runner/work/Raven.KeyManagementService/Raven.KeyManagementService/CertificateValidatorSample/Program.cs 中的 ClausAppel.CertificateValidatorSample.Program.Main(String[] args):第 13 行
有人知道该怎么办吗?我是否需要安装一些软件或对我的 Linux 机器进行其他更改?
我可以允许这个特定的状态标志,但我非常不想这样做。这会引入很多漏报(即,链无效,但如果我们允许此状态标志,则看起来有效)。
我尝试使用 X509Store 添加父证书,但这似乎没有帮助。
编辑:并不是每台 Linux 机器上都会出现这个问题。我已经在一些运行 Ubuntu 20.04 (Focal Fossa) 和 Ubuntu 22.04 (Jammy Jellyfish) 的 Linux 机器上看到过这种情况。但我也看到它在一些运行 Ubuntu 20.04 (Focal Fossa) 的机器上通过。所以这显然取决于 Linux 运行器上安装的设置和软件。
我找到了一个解决方法:我的叶证书包含X509KeyUsageFlags.None。显然,一些较新的密码学库认为这是一个错误。当我们更改证书以使用另一个标志时,它们开始在所有 Linux 版本上工作。
我能够在以下 Linux Docker 映像上重现该错误:
mcr.microsoft.com/dotnet/aspnet:6.0-alpine
mcr.microsoft.com/dotnet/aspnet:6.0-jammy
即使使用 X509KeyUsageFlags.None,此 Linux Docker 映像也会接受证书:
mcr.microsoft.com/dotnet/aspnet:6.0-focal