根据自签名证书颁发机构验证服务器证书

本文关键字:证书 机构 验证 服务器 | 更新日期: 2023-09-27 18:33:15

我有自定义服务器/客户端应用程序,它们使用 SSL 加密的 TCP 连接(自定义协议(相互通信。为了设置服务器证书,我创建了一个自签名证书颁发机构,并使用它来签署证书以供服务器使用。在客户端,我想验证我连接到的服务器的证书是否由我的自签名 CA 签名。

通过使用 load_verify_file(( 函数为 ssl::context 提供自签名 CA 证书,我能够在 C++ 中通过 boost 使其工作。我想在 C# 客户端中实现相同的功能,但 .NET SSL 内容似乎对信任不在 Windows 信任存储中的证书更加严格。

到目前为止,我在搜索中发现了几个部分解决方案。显然,X509链是用于验证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;
}

根据自签名证书颁发机构验证服务器证书

我怀疑您的私有 CA 证书未安装在当前系统(运行代码的位置(上或安装不正确。根 CA 证书必须安装在计算机 stire 的受信任根 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;

其中cacert是根 CA 证书。