[英]C# - Verify client certificate signed by proper root
我知道对此争论有很多疑问,但是我已经坚持了几天,所以我在这里。 我有一个根证书和一个客户端证书。 我需要在C#Web API项目中复制命令openssl verify -CAfile ca.pem client.pem
执行的操作。
这是我现在所知道的(希望它是真的):
Verify()
方法实际上验证证书是由授权机构签名的。 就像格式控件一样。 哪位大律师在证书上签字都没有关系。 X509 Chain
是必经之路。 将CA证书添加到其他商店中,因为我不会将证书安装到Windows中。 然后构建通过客户端证书的证书。 让魔术发生吧! 不幸的是,我在配置上遇到了一些问题。 让我更清楚地举例说明
private bool VerifyCertificate(X509Certificate2 client)
{
X509Chain chain = new X509Chain();
var stringCert = WebConfigurationManager.AppSettings["CACertificate"];
var byteCert = Encoding.ASCII.GetBytes(stringCert);
var authority = new X509Certificate2(byteCert);
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreWrongUsage;
chain.ChainPolicy.ExtraStore.Add(authority);
// Do the preliminary validation.
if (!chain.Build(client))
return false;
return true;
}
在此示例中,程序返回false
。 该构建未通过。 我确定问题出在ChainPolicy properties
所以我尝试了另一种配置
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
chain.ChainPolicy.VerificationTime = DateTime.Now;
chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 0, 0);
但这并不会验证任何事情 ,实际上,使用我的ca cert方法会返回true
而使用另一个ca证书(我没有使用它来签署我的客户端证书),该方法也会返回true
。
我搜索了C#的OpenSSL包装器,但找到了它,但不幸的是它是基于旧库的,并且该回购协议已不再使用。 另外,如果可能的话,我将仅使用.net框架实现我的目标。
各位,快速回顾一下。 我想检查的是,只有由我的ca证书确定的证书才能通过验证,而所有其他证书都必须停止。
预先感谢您的任何帮助
ExtraStore
,它提供了额外的证书来帮助完成整个链。 它不提供信任数据。
为了确定证书是否由您想要的CA颁发,您需要执行以下操作:
private static readonly X509Certificate2 s_trustedRoot = ObtainTheRoot();
private static readonly byte[] s_normalizedRoot = s_trustedRoot.RawData;
private bool VerifyCertificate(X509Certificate2 candidate)
{
X509Chain chain = new X509Chain();
// set all the things you need to set to make it build
if (!chain.Build(candidate))
return false;
// Check that the root certificate was the expected one.
X509ChainElementCollection elements = chain.ChainElements;
return elements[elements.Count - 1].Certificate.RawData.SequenceEqual(s_normalizedRoot);
}
我假设它在过程开始后不会更改,因此将其cert和标准化字节形式提升为静态。 如果证书可以动态更改,则应进行相应调整。
找到问题。 就我而言,这是正确的回应。
private bool VerifyCertificate(X509Certificate2 client)
{
X509Chain chain = new X509Chain();
var stringCert = WebConfigurationManager.AppSettings["CACertificate"];
var byteCert = Encoding.ASCII.GetBytes(stringCert);
var authority = new X509Certificate2(byteCert);
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
chain.ChainPolicy.ExtraStore.Add(authority);
// Do the preliminary validation.
if (!chain.Build(client))
return false;
// This piece makes sure it actually matches your known root
var valid = chain.ChainElements
.Cast<X509ChainElement>()
.Any(x => x.Certificate.Thumbprint == authority.Thumbprint);
if (!valid)
return false;
return true;
}
现在,调试应用程序我有一些注意事项:
我的意思是,使用由ca签名的证书或使用自签名证书的方法,如果我使用受信任的证书,则方法始终返回true
BUT,它将在chain.ChainElements
内添加证书chain.ChainElements
否则不添加任何内容。
我需要了解这件事,但是我所做的所有测试都表明该方法有效
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.