为了执行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);