C#如何validationRoot-CA-Cert证书(x509)链?

假设我有三个证书(Base64格式)

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

如何在C#中validation证书和证书路径/链? (所有这三个证书可能都不在我的计算机证书库中)

编辑 :BouncyCastle具有validationfunction。 但我试图不使用任何第三方库。

  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)签名,则会出现exception。 这正是我想要的。

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

 static bool VerifyCertificate(byte[] primaryCertificate, IEnumerable 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); } 

如果需要, X509Chain将包含有关Build() == false后validation失败的其他信息。

编辑:这只会确保您的CA有效。 如果要确保链条相同,可以手动检查指纹。 您可以使用以下方法来确保认证链是正确的,它期望链的顺序为: ..., INTERMEDIATE2, INTERMEDIATE1 (Signer of INTERMEDIATE2), CA (Signer of INTERMEDIATE1)

 static bool VerifyCertificate(byte[] primaryCertificate, IEnumerable 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链,因此最好调试并逐步执行代码。