2011-09-07 579 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