我有自定义的服务器/客户端应用程序,它们使用SSL加密的TCP连接(自定义协议)进行通信。为了设置服务器证书,我创建了一个自签名证书颁发机构,并使用它来签署服务器要使用的证书。在客户端方面,我希望验证我连接到的服务器的证书是由我的自签名CA签署的。
我能够在C++中使用boost通过将自签名CA证书提供给ssl::context的load_verify_file()函数来使其工作。我希望在C#客户端中实现相同的功能,但.NET SSL似乎更严格地信任不在Windows信任存储中的证书。
我在搜索中找到了几个部分解决方案。显然 X509Chain 是用于验证 SSL 证书的类。我尝试了 像这样的代码,但是手动创建的链仍然抱怨根证书不受信任,就像传递到验证函数中的原始链一样。有一个选项可以 忽略未知的证书颁发机构,但那似乎意味着它将接受 任何 自签名证书,这绝对不是我想要的。
我能够在C++中使用boost通过将自签名CA证书提供给ssl::context的load_verify_file()函数来使其工作。我希望在C#客户端中实现相同的功能,但.NET SSL似乎更严格地信任不在Windows信任存储中的证书。
我在搜索中找到了几个部分解决方案。显然 X509Chain 是用于验证 SSL 证书的类。我尝试了 像这样的代码,但是手动创建的链仍然抱怨根证书不受信任,就像传递到验证函数中的原始链一样。有一个选项可以 忽略未知的证书颁发机构,但那似乎意味着它将接受 任何 自签名证书,这绝对不是我想要的。
这段代码似乎最接近我想要的,但如上所述,我的问题是它仍然抱怨我添加到 ExtraStore 的证书是自签名的。有没有办法说服 X509Chain 相信我正在给它的证书?
bool remoteCertificateValidationCallback(
object sender, X509Certificate certificate, X509Chain chain,
SslPolicyErrors sslPolicyErrors)
{
// make sure certificate was signed by our CA cert
X509Chain verify = new X509Chain();
verify.ChainPolicy.ExtraStore.Add(secureClient.CertificateAuthority); // add CA cert for verification
//verify.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; // this accepts too many certificates
verify.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; // no revocation checking
verify.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
if (verify.Build(new X509Certificate2(certificate)))
{
return true; // success?
}
return false;
}
X509Chain.Build
内部调用CertCreateCertificateChainEngine
函数,该函数依赖于本地证书存储来建立信任。您可以通过移除外部 IF 语句并且不使用方法结果来避免这个要求。对于您的确切问题来说这是足够的。 - Crypt32chain
变量(其中包含来自服务器的正确链)。我可以只检查chain.ChainStatus
是否仅包含UntrustedRoot
,以确保该链也是有效的,而不仅仅是在末尾添加了CA吗? - plasmoidia