【问题标题】:How do I validate that a certificate was created by a particular certification authority?如何验证证书是由特定证书颁发机构创建的?
【发布时间】:2011-09-23 17:35:12
【问题描述】:

我有一个 Windows 证书颁发机构,用于通过 .net / c# 颁发客户端身份验证证书。通过COM调用证书颁发机构的API,我已经能够成功地让它以编程方式颁发证书。我在设置客户端时颁发了新证书。

在运行时,这些客户端将证书附加到我的服务器的请求中。如何以编程方式验证 X509Certificate2 是否由我的证书颁发机构的根证书签名(并拒绝任何其他来源签名的证书)?

【问题讨论】:

  • 应该在 security.se 上(也许)
  • 为什么?我的问题是如何验证登录代码...
  • 你找到编码这个的方法了吗?

标签: c# .net security certificate


【解决方案1】:

我已经做了很多。这里有一些你可以使用的简单代码。

if (!isChainValid) 块中的部分是制作一个漂亮的错误消息。如果您不想使用它,则不必使用它,但如果无法构建链,则应该抛出错误。链元素是检查您的根所必需的。

X509Certificate2 authority = GetAuthorityCertificate();
X509Certificate2 certificateToValidate = GetCertificateToValidate();

X509Chain chain = new X509Chain();
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
chain.ChainPolicy.RevocationFlag = X509RevocationFlag.ExcludeRoot;
chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllowUnknownCertificateAuthority;
chain.ChainPolicy.VerificationTime = DateTime.Now;
chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan(0, 0, 0);

// This part is very important. You're adding your known root here.
// It doesn't have to be in the computer store at all. Neither certificates do.
chain.ChainPolicy.ExtraStore.Add(authority);

bool isChainValid = chain.Build(certificateToValidate);

if (!isChainValid)
{
    string[] errors = chain.ChainStatus
        .Select(x => String.Format("{0} ({1})", x.StatusInformation.Trim(), x.Status))
        .ToArray();
    string certificateErrorsString = "Unknown errors.";

    if (errors != null && errors.Length > 0)
    {
        certificateErrorsString = String.Join(", ", errors);
    }

    throw new Exception("Trust chain did not complete to the known authority anchor. Errors: " + certificateErrorsString);
}

// 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)
{
    throw new Exception("Trust chain did not complete to the known authority anchor. Thumbprints did not match.");
}

【讨论】:

  • @HelloWorld 好吧,如果我今天写这篇文章,无论如何我都会使用if (errors?.Length &gt; 0)。 :) C# 6。很高兴知道;我没有深入研究 ToArray() 实现来看看如果Select()IEnumerable 没有返回结果会发生什么。
  • @ChrisBenard 检查证书是否与您的已知根匹配的代码真的可以吗?那段代码应该匹配做这样的事情并且几乎总是返回true:chain.ChainElements.Cast&lt;X509ChainElement&gt;().All(x =&gt; x.Certificate.Thumbprint != "XX");
  • @MattiasNordqvist 如果证书正常(未过期/撤销/等),由于使用了X509VerificationFlags.AllowUnknownCertificateAuthority,这将是正确的。稍后通过指纹检查是必要的,以检查您使用ExtraStore.Add() 放置在链中的权限。
  • 我有根证书和中间证书(由根签名),需要验证由中间人签名的客户端证书。在这种情况下,是否需要在ExtraStore中添加root和intermediate,并且需要检查指纹与哪个证书?
  • @Varsh 听起来您确实需要添加根和中间体并检查根的指纹。
【解决方案2】:

您也可以使用内置方法Verify()X509Certificate2

X509Certificate2 certificateToValidate = GetCertificateToValidate();
bool valid = certificateToValidate.Verify()

https://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate2.verify.aspx

【讨论】:

    【解决方案3】:

    如果你说你有一个 root(自签名)证书,那么你唯一的选择是让这个根证书在你的服务器上可用(当然没有私钥)并执行针对您的根证书的证书验证过程。这是 Web 客户端验证服务器证书链的镜像情况。

    【讨论】:

    • 我确实有这种情况。我会澄清我的问题,但我正在寻找验证 C# 签名所需的特定代码。
    • @Jeffrey 我知道这是如何在我们的 SecureBlackbox for .NET 中完成的,但不知道它是如何在纯 .NET Framework 中完成的。
    • 可能有更好的方法,但请查看X509Chain 类。文档示例显示了沿着链检查每个元素的代码。
    猜你喜欢
    • 2012-10-31
    • 2018-06-19
    • 2012-04-18
    • 2017-10-19
    • 2016-01-01
    • 1970-01-01
    • 2011-07-28
    • 2021-04-13
    • 1970-01-01
    相关资源
    最近更新 更多