2011-09-07 27 views
13

はのは、私はC#で証明書と証明書パス/チェーンを検証するにはどうすればよい(Base64形式で)3つの証明書C#Root-CA-Cert証明書(x509)チェーンを検証するにはどうすればよいですか?

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

があるとしましょうか? BouncyCastleは、検証する機能を持っています

編集は、(すべてのこれら3つの本命は私のコンピュータの証明書ストアにできない場合があります)。しかし、私はサードパーティのライブラリを使用しないようにしています。 CER1をcert2(CAまたはルート)によって署名されていない場合

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()); 

、例外が存在するであろう。これはまさに私が欲しいものです。

答えて

0

'X509Certificate2.Verify()'を見てみましょう。それは助けになるはずです。

+0

どのように私は一度に3を確認することができますか?どのように私は3つの証明書をチェーンすることができますか? – Jacob

+0

私はわからないが、一時ストアを作成しよう[X509Store](http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509store.aspx)。そのストアにすべての証明書を追加します。この後、最も低い証明書でvalidateを呼び出す必要があります。 – 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); 
} 

X509Chain

Build() == 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

ありがとうございます。しかしchain.Buildが本命の妥当性を検証しているように見えます。私はわざわざ「additionalCertificates」で異なる発行者証明書を入れて、結果が「真」である:( – Jacob

+0

@Jacob、新しい方法を試してみてください。 –

+0

おかげでジョナサン。しかし、動作していません(正確なパス/チェーンであっても)拇印の方法が異なるため、拇印方法が機能しません – Jacob

関連する問題