繁体   English   中英

C#-验证由正确的根签名的客户端证书

[英]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;
    }

现在,调试应用程序我有一些注意事项:

  1. .Build()方法应该做什么?

我的意思是,使用由ca签名的证书或使用自签名证书的方法,如果我使用受信任的证书,则方法始终返回true BUT,它将在chain.ChainElements内添加证书chain.ChainElements否则不添加任何内容。

我需要了解这件事,但是我所做的所有测试都表明该方法有效

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM