根据自签名证书颁发机构验证服务器证书 [英] verify server certificate against self-signed certificate authority

查看:261
本文介绍了根据自签名证书颁发机构验证服务器证书的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我能够获得此证书通过使用load_verify_file()函数为ssl :: context提供自签名的CA证书,在Boost中使用C ++。我想在C#客户端中实现相同的功能,但是.NET SSL似乎对信任不在Windows信任库中的证书更为严格。



<到目前为止,我在搜索中发现了一些局部解决方案。显然, X509Chain是用于验证SSL证书的类。我已经尝试过这样的代码,但是手动创建的链仍然抱怨根证书不受信任,就像原始链被传递到验证功能。可以选择忽略未知的证书颁发机构,但这似乎意味着它将接受任何 >自签名证书,这绝对不是我想要的。



这似乎与我想要的代码最接近,但是如上所述,它仍然抱怨我添加到ExtraStore的证书是自签名的。有什么办法说服X509Chain信任我提供的证书?

  bool remoteCertificateValidationCallback(
对象发送者, X509Certificate证书,X509Chain链,
SslPolicyErrors sslPolicyErrors)
{
//确保证书已由我们的CA证书签署
X509Chain verify = new X509Chain();
verify.ChainPolicy.ExtraStore.Add(secureClient.CertificateAuthority); //添加CA证书进行验证
//verify.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority; //这接受太多的证书
verify.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; //没有吊销检查
verify.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
if(verify.Build(new X509Certificate2(certificate)))
{
返回true; //成功?
}
返回false;
}


解决方案

我怀疑您的私人CA证书未安装在当前系统(运行代码的地方)上,或者安装不正确。根CA证书必须安装在计算机搅动的受信任的根CA容器中,而不是当前用户存储中。默认情况下, X509Chain 使用计算机商店查找受信任的锚点。



此外,您的代码不会执行您所执行的操作想。它将接受并传递任何公共信任的根CA。相反,您需要比较 X509Chain.ChainElements 中的最后一个元素,是否包含的证书是您期望的证书(通过比较指纹值)。愚蠢的修正应适用:

  if(verify.Build(new X509Certificate2(certificate)))
{
返回verify.ChainElements [verify.ChainElements.Count-1]
.Certificate.Thumbprint == cacert.thumbprint; //成功?
}
返回false;

其中 cacert 是您的根CA证书。


I have custom server/client applications that communicate to each other using an SSL-encrypted TCP connection (custom protocol). To setup the server certificate, I have created a self-signed certificate authority and used that to sign a certificate for the server to use. On the client side, I would like to verify that the certificate of the server I am connecting to was signed by my self-signed CA.

I was able to get this working in C++ with boost by giving the ssl::context the self-signed CA certificate using the load_verify_file() function. I would like to implement the same functionality in a C# client, but the .NET SSL stuff seems to be much more stringent about trusting certificates that are not in the Windows trust store.

I have found several partial solutions in my searching around so far. Apparently X509Chain is the class to use to verify SSL certificates. I have tried code like this but the manually created chain still complains that the root certificate is untrusted, just like the original chain that gets passed into the verification function. There is an option to ignore unknown certificate authorities, but that seems to mean that it will accept any self-signed certificate, which is definitely not what I want.

This is the code that seems to come closest to what I want, but as stated above, I have the problem that it still complains about the certificate I add to the ExtraStore being self-signed. Is there any way to convince X509Chain to trust the certificate I am giving it?

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;
}

解决方案

I suspect that your private CA certificate is not installed on the current system (where you run the code) or it is installed incorrectly. The root CA certificate MUST be installed in the Trusted Root CAs container of Computer stire, not in the current user store. By default, X509Chain uses computer store to lookup for trusted anchors.

Also, your code do not perform what you want. It will accept and pass for any publically trusted root CA. Instead, you need to compare the last element in the X509Chain.ChainElements, whether the contained certificate is the one you are expecting (by comparing thumbprint values). The foolowing fix should apply:

if (verify.Build(new X509Certificate2(certificate)))
{
    return verify.ChainElements[verify.ChainElements.Count - 1]
        .Certificate.Thumbprint == cacert.thumbprint; // success?
}
return false;

where cacert is your root CA certificate.

这篇关于根据自签名证书颁发机构验证服务器证书的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆