使用自定义证书存储构建 X509 链



为了执行SSL证书验证,我正在为System.Net.ServicePointManager.ServerCertificateValidationCallback分配一个回调,然后我尝试自己构建X.509链,以检查服务器证书是否由我信任的CA集合颁发。

我知道我可以扩展要在链构建期间使用的证书集合(通过向X509Chain.ChainPolicy.ExtraStore添加新项( - 但这用于信任不在本地证书存储中的其他证书。

怎样才能将连锁店构建限制在我自己以编程方式构建的给定商店中?我找不到一种方法来使用调用X509Chain.Build(X509Certificate2)时使用的自定义X509Store对象。

AFAIK,无法在 .NET 中限制一组受信任的根(受信任的锚点(。但是,您可以通过互操作调用本机(类似C++(CryptoAPI 函数。

基本上,您需要使用 CertCreateCertificateChainEngine 函数并使用自定义的输入链接引擎配置结构:CERT_CHAIN_ENGINE_CONFIG。

你将需要创建一个虚拟(无需在 Windows 证书存储中显式注册(存储,添加一组你选择的受信任证书。获取存储句柄/指针,并将其传递到 CERT_CHAIN_ENGINE_CONFIG 对象的 hRestrictedRoot 参数中。在这种情况下,将不会使用默认根存储。该函数返回一个句柄HCERTCHAINENGINE该句柄,然后可以在 CertGetCertificateChain 函数调用(发生实际链验证的地方(中使用。

如果你想限制(vs "替换"(信任列表,这很容易,只需使用回调中提供的链,看看它是否符合要求。

HashSet<X509Certificate2> s_allowedRoots = new HashSet<X509Certificate2>
{
    trustedCertA,
    trustedCertB,
    ...
};
...
// In your callback
if (errors != SslPolicyErrors.None)
{
    return false;
}
X509Certificate2 chainRoot = chain.ChainElements[chain.ChainElements.Count - 1].Certificate;
return s_allowedRoots.Contains(chainRoot);

最新更新