C # Как я могу проверить цепочку сертификатов Root-CA-Cert (x509)? - PullRequest
18 голосов
/ 07 сентября 2011

Допустим, у меня есть три сертификата (в формате Base64)

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), будет исключение. Это именно то, что я хочу.

1 Ответ

28 голосов
/ 07 сентября 2011

Класс 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 действителен. Если вы хотите убедиться, что цепочка идентична, вы можете проверить отпечатки вручную. Вы можете использовать следующий метод, чтобы убедиться, что цепочка сертификации правильная, она ожидает цепочку в порядке: ..., 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, поэтому было бы лучше отладить и пройтись по коду.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...