确定证书是主机证书、中间证书还是根证书

Idenitfy if certificate is a host, intermediate, or root cert

我需要一种方法,在给定 X509Certificate2 对象列表的情况下,将每个对象分类为根证书、中间证书或主机证书。

我在 AWS 的 docker 容器中有一个 TCP 服务 运行。我已经建立了一个秘密管理系统和外部配置系统来为 TLS 服务提供证书。但是,证书是 PEM,这在 C# 中是非常痛苦的。在过去的 8 年里,在涉及私钥时甚至加载 PEM 证书时,我已经努力了大约 5 次,我终于用 dotnet 核心中提供的一些新语法彻底解决了这个问题。所以耶。

现在我的应用程序拥有带有私钥的证书和链,但仍然无法使用它们,因为 AuthenticateAsServer 方法接口不允许您提供链。相反,您提供一个证书,然后如果可以的话,它将从证书存储中挖掘出一条链,然后您必须在另一端查看该链是否出来了。 (我会用一个小时的长篇大论来讲述我对这种模式的感受)因为我无法提供链,所以我唯一的选择是在调用 AuthenticateAsServer 之前 install 链,这样超级不透明的黑色盒子会找到它们并发送它们。

问题来了。我的链是一个很大的字符串,您可以通过将相关的 OpenSSL 创建的证书文件组合在一起来获得这种字符串。我已经编写了一些代码将该文本拆分为证书块,然后初始化 X509Certificate2 对象的集合,我可以 foreach 并将每个对象安装到商店中。但是哪家店?我需要一种方法来检查每一个并知道它应该进入哪个商店。

这是我在伪代码中的工作思路

bool isSelfSigned = cert.Issuer == cert.Subject;
bool isCa = HasBasicConstraintCA();

if (isCa)
{
   if (isSelfSigned) root=true;
   else intermediate=true;
}
else if(some hopefully affirmative condition)
{
   host=true;
}

考虑到这种情况,这合理吗?这样的逻辑会不会中了意想不到的陷阱?

是否有任何我可以检查主机证书的肯定条件,除了它不是其他两个?

你的逻辑基本正确;请注意,对于最终实体证书(在您的术语主机证书中),以下值是可能的;

  1. 不存在 basicConstraint 标志
  2. basicConstraint:CA:False 存在

在上述两种情况下,它都可以解释为终端实体(主机)证书。请确保您的 HasBasicConstraintCA() 函数检查这两种情况。除了逻辑看起来简单而精彩。