2011-09-07 577 views
13

比方说,我有三个证(以Base64格式)C#如何验证根CA证书(x509)链?

Root 
| 
--- CA 
    | 
    --- Cert (client/signing/whatever) 

我如何可以验证在C#中的证书和证书路径/链? (所有这三个证书可能不在我的电脑证书商店)

编辑:BouncyCastle有验证功能。但我试图不使用任何第三方库。

byte[] b1 = Convert.FromBase64String(x509Str1); 
    byte[] b2 = Convert.FromBase64String(x509Str2); 
    X509Certificate cer1 = 
     new X509CertificateParser().ReadCertificate(b1); 
    X509Certificate cer2 = 
     new X509CertificateParser().ReadCertificate(b2); 
    cer1.Verify(cer2.GetPublicKey()); 

如果cer1未由cert2(CA或root)签名,则会有异常。这正是我想要的。

回答

0

看看'X509Certificate2.Verify()'。它应该有所帮助。

+0

我该如何验证3一次?我如何链接3个证书? – Jacob

+0

我不确定,但尝试创建临时存储[X509Store](http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509store.aspx)。将所有证书添加到该商店。在此之后,您应该调用最低证书上的验证。 – MichaelMocko

20

X509Chain类旨在执行此操作,您甚至可以自定义它如何执行链构建过程。

static bool VerifyCertificate(byte[] primaryCertificate, IEnumerable<byte[]> additionalCertificates) 
{ 
    var chain = new X509Chain(); 
    foreach (var cert in additionalCertificates.Select(x => new X509Certificate2(x))) 
    { 
     chain.ChainPolicy.ExtraStore.Add(cert); 
    } 

    // You can alter how the chain is built/validated. 
    chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; 
    chain.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreWrongUsage; 

    // Do the validation. 
    var primaryCert = new X509Certificate2(primaryCertificate); 
    return chain.Build(primaryCert); 
} 

X509ChainBuild() == false后,将包含有关验证失败的更多信息,如果你需要它。

编辑:这只会确保您的CA有效。如果你想确保链条是相同的,你可以手动检查指纹。您可以使用下面的方法,以确保证书链是正确的,它预计链的顺序:​​

static bool VerifyCertificate(byte[] primaryCertificate, IEnumerable<byte[]> additionalCertificates) 
{ 
    var chain = new X509Chain(); 
    foreach (var cert in additionalCertificates.Select(x => new X509Certificate2(x))) 
    { 
     chain.ChainPolicy.ExtraStore.Add(cert); 
    } 

    // You can alter how the chain is built/validated. 
    chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; 
    chain.ChainPolicy.VerificationFlags = X509VerificationFlags.IgnoreWrongUsage; 

    // Do the preliminary validation. 
    var primaryCert = new X509Certificate2(primaryCertificate); 
    if (!chain.Build(primaryCert)) 
     return false; 

    // Make sure we have the same number of elements. 
    if (chain.ChainElements.Count != chain.ChainPolicy.ExtraStore.Count + 1) 
     return false; 

    // Make sure all the thumbprints of the CAs match up. 
    // The first one should be 'primaryCert', leading up to the root CA. 
    for (var i = 1; i < chain.ChainElements.Count; i++) 
    { 
     if (chain.ChainElements[i].Certificate.Thumbprint != chain.ChainPolicy.ExtraStore[i - 1].Thumbprint) 
      return false; 
    } 

    return true; 
} 

我不能对此进行测试,因为我没有跟我一个完整的CA链,所以最好调试一遍代码。

+0

谢谢。但我故意将不同的颁发者证书放在“additionalCertificates”中,结果是“true”:( – Jacob

+0

@Jacob,尝试新方法。 –

+0

感谢Jonathan。但是不工作。它看起来像chain.Build正在验证证书的有效性。不是证书路径只要证书是有效的(证书链/路径是错误的),结果是真的。thumbprint方法不起作用,因为所有的指纹都不同(即使在正确的路径/链中) – Jacob