問題描述
假設我有三個證書(Base64 格式)
Let's say I have three certificates (in Base64 format)
Root
|
--- CA
|
--- Cert (client/signing/whatever)
如何在 C# 中驗證證書和證書路徑/鏈?(所有這三個證書可能不在我的計算機證書存儲中)
How can I validate the certs and certificate path/chain in C#? (All those three certs may not be in my computer cert store)
編輯:BouncyCastle 具有驗證功能.但我盡量不使用任何第三方庫.
Edit: BouncyCastle has the function to verify. But I'm trying not to use any third-party library.
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)簽名,就會出現異常.這正是我想要的.
If the cer1 is not signed by cert2 (CA or root), there will be exception. This is exactly what I want.
推薦答案
X509Chain
類就是為此而設計的,您甚至可以自定義它如何執行鏈構建過程.
The X509Chain
class was designed to do this, you can even customize how it performs the chain building process.
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);
}
如果您需要,X509Chain
將包含有關 Build() == false
之后驗證失敗的附加信息.
The X509Chain
will contain additional information about the validation failure after Build() == false
if you need it.
這只會確保您的 CA 有效.如果要確保鏈相同,可以手動檢查指紋.可以使用下面的方法來保證認證鏈是正確的,它期望鏈的順序是:..., INTERMEDIATE2, INTERMEDIATE1 (Signer of INTERMEDIATE2), CA (Signer of INTERMEDIATE1)
This will merely ensure that your CA's are valid. If you want to ensure that the chain is identical you can check the thumbprints manually. You can use the following method to ensure that the certification chain is correct, it expects the chain in the order: ..., INTERMEDIATE2, INTERMEDIATE1 (Signer of INTERMEDIATE2), CA (Signer of INTERMEDIATE1)
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 鏈,因此最好調試并逐步執行代碼.
這篇關于C# 如何驗證 Root-CA-Cert 證書 (x509) 鏈?的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!