我如何验证证书是由特定的认证机构产生的?是由、认证机构、证书

2023-09-05 22:59:37 作者:一碗葡萄柚

我有我使用发行通过.NET / C#客户端身份验证证书的Windows证书颁发机构。我已经能够成功地得到它的编程方式颁发证书,通过调用COM通过权威认证的API。我发出了一个新的证书时,我成立了一个客户端。

I have a Windows certification authority that I am using to issue client authentication certificates via .net / c#. I have been able to successfully get it to issue certificates programmatically by calling the certification authority's API through COM. I issue a new certificate when I set up a client.

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

At runtime, these clients attach the certificates to requests to my server. How can I verify programmatically that an X509Certificate2 was signed by the root certificate of my certificate authority (and reject certificates signed by any other source)?

推荐答案

我做这个的很多。下面是一些简单的code就可以使用。

I've done this a lot. Here's some easy code you can use.

如果(!isChainValid)块的部分是做一个pretty的错误消息。您没有使用,如果你不想要的,但你应该抛出一个错误,如果不能建立的产业链。链要素是必需的检查你的根。

The part in the if (!isChainValid) block is to make a pretty error message. You don't have to use that if you don't want, but you should throw an error if the chain cannot be built. The chain elements are necessary to check for your root.

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
if (!chain.ChainElements
    .Cast<X509ChainElement>()
    .Any(x => x.Certificate.Thumbprint == authority.Thumbprint))
{
    throw new Exception("Trust chain did not complete to the known authority anchor. Thumbprints did not match.");
}