我有自定义服务器/客户端应用程序,它们使用 SSL 加密的 TCP 连接(自定义协议)相互通信。为了设置服务器证书,我创建了一个自签名证书颁发机构,并使用它来签署证书以供服务器使用。在客户端,我想验证我正在连接的服务器的证书是否由我的自签名 CA 签名。
通过使用 load_verify_file() 函数向 ssl::context 提供自签名 CA 证书,我能够在 C++ 中使用 boost 来实现此功能。我想在 C# 客户端中实现相同的功能,但 .NET SSL 的内容似乎对于信任不在 Windows 信任存储中的证书要严格得多。
到目前为止,我在搜索中找到了几个部分解决方案。显然X509Chain 是用于验证 SSL 证书的类。我试过代码像这样但手动创建的链仍然抱怨根证书不受信任,就像传递到验证函数的原始链一样。有一个选项可以忽略未知的证书颁发机构,但这似乎意味着它会接受any自签名证书,这绝对不是我想要的。
这是似乎最接近我想要的代码,但如上所述,我遇到的问题是它仍然抱怨我添加到 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;
}
我怀疑您的私有 CA 证书未安装在当前系统(运行代码的位置)上或者安装不正确。根 CA 证书必须安装在计算机的受信任根 CA 容器中,而不是安装在当前用户存储中。默认情况下,X509Chain
使用计算机商店查找可信锚点。
此外,您的代码无法执行您想要的操作。它将接受并传递任何公共信任的根 CA。相反,您需要比较中的最后一个元素X509Chain.ChainElements
,所包含的证书是否是您期望的证书(通过比较指纹值)。应应用以下修复:
if (verify.Build(new X509Certificate2(certificate)))
{
return verify.ChainElements[verify.ChainElements.Count - 1]
.Certificate.Thumbprint == cacert.thumbprint; // success?
}
return false;
where cacert
是您的根 CA 证书。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)