简体   繁体   English

如何验证证书是否由特定证书颁发机构创建?

[英]How do I validate that a certificate was created by a particular certification authority?

I have a Windows certification authority that I am using to issue client authentication certificates via .net / c#. 我有一个Windows证书颁发机构,我用它来通过.net / c#发出客户端身份验证证书。 I have been able to successfully get it to issue certificates programmatically by calling the certification authority's API through COM. 通过COM调用证书颁发机构的API,我已经能够成功地以编程方式颁发证书。 I issue a new certificate when I set up a client. 我在设置客户端时发出新证书。

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)? 如何以编程方式验证X509Certificate2是否由我的证书颁发机构的根证书签名(并拒绝由任何其他来源签名的证书)?

I've done this a lot . 我做了很多 Here's some easy code you can use. 这里有一些你可以使用的简单代码。

The part in the if (!isChainValid) block is to make a pretty error message. if (!isChainValid)块中的部分是一个非常错误的消息。 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
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.");
}

You can also use the built in method Verify() for X509Certificate2 . 您还可以使用X509Certificate2的内置方法Verify()

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

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

If you say you have a root (which is self-signed) certificate, then your only option is to keep this root certificate available on your server (without the private key of course) and perform certificate validation procedure against your root certificate. 如果您说您有一个root (自签名)证书,那么您唯一的选择是在服务器上保留此根证书(当然没有私钥)并对您的根证书执行证书验证程序。 This is a mirrored situation to the web client validating server certificate chain. 这是Web客户端验证服务器证书链的镜像情况。

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

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