我知道这个争论有很多问题,但是我已经坚持了几天,所以我在这里。
我有一个根证书和一个客户端证书。我需要在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证书确定的证书才能通过验证,所有其他证书都必须停止。
在此先感谢您的帮助
答案 0 :(得分:0)
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);
}
我假设它的证书和规范化字节形式将其提升为静态,前提是假设一旦过程开始它们就不会改变。如果证书可以动态更改,则应进行相应调整。
答案 1 :(得分:0)
找到问题。 就我而言,这是正确的答案。
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
,但是如果我使用受信任的证书,它将在chain.ChainElements
内添加证书否则,不添加任何内容。
我需要了解这一点,但是我所做的所有测试都表明该方法有效