2011-09-07 18 views
13

Digamos que tengo tres certificados (en formato Base64)C# ¿Cómo puedo validar una cadena de certificado Root-CA-Cert (x509)?

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

¿Cómo puedo validar los certs y certificado de ruta/cadena en C#? (Todas esas tres CERT pueden no estar en mi tienda cert ordenador)

Editar: BouncyCastle tiene la función de verificar. Pero estoy tratando de no usar ninguna biblioteca de terceros.

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

Si el cer1 no está firmado por cert2 (CA o raíz), habrá una excepción. Esto es exactamente lo que quiero.

Respuesta

0

Eche un vistazo a 'X509Certificate2.Verify()'. Debería ayudar.

+0

¿cómo puedo verificar 3 a la vez? ¿Cómo puedo encadenar los 3 certs? – Jacob

+0

No estoy seguro, pero intente crear el almacén temporal [X509Store] (http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509store.aspx). Luego agregue todos los certificados en esa tienda. Después de esto, debe llamar validar en el certificado más bajo. – MichaelMocko

20

La clase X509Chain fue diseñada para hacer esto, incluso puede personalizar cómo realiza el proceso de construcción de cadena.

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

El X509Chain contendrá información adicional sobre el fallo de validación después de Build() == false si lo necesita.

Editar: Esto simplemente se asegurará de que sus CA sean válidas. Si desea asegurarse de que la cadena sea idéntica, puede verificar manualmente las huellas dactilares. Se puede utilizar el siguiente método para asegurarse de que la cadena de certificación es correcta, se espera que la cadena en el orden: ..., 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; 
} 

Soy incapaz de probar esto porque no tengo una cadena completa CA conmigo , por lo que sería mejor depurar y recorrer el código.

+0

Gracias. Pero intencionalmente coloqué diferentes cert de emisor en "additionalCertificates" y el resultado es "verdadero" :( – Jacob

+0

@Jacob, pruebe el nuevo método. –

+0

Gracias Jonathan, pero no funciona. Parece que chain.Build está verificando la validez de los certs No es la ruta de certificación. Siempre que los certs sean válidos (aunque la cadena de certificación/ruta sea incorrecta) el resultado es verdadero. El método de huella digital no funciona porque todas las huellas digitales son diferentes (incluso en la ruta/cadena correcta) – Jacob

Cuestiones relacionadas