Как программно импортировать pfx с цепочкой сертификатов в хранилище сертификатов? - PullRequest
21 голосов
/ 04 февраля 2012

Я пытаюсь программно импортировать сертификат X509 (pfx / PKCS # 12) в хранилище сертификатов моего локального компьютера.Этот конкретный сертификат имеет цепочку сертификатов, путь сертификации выглядит примерно так:

  • Корневой сертификат CA
    • Сертификат организации CA
      • Сертификат организации 2CA
        • Мой сертификат

Код, который я использую, выглядит следующим образом:

cert = new X509Certificate2(pathToCert, password);

if (cert != null)
{
    var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
    store.Open(OpenFlags.ReadWrite);
    if (!store.Certificates.Contains(cert))
    {
        store.Add(cert);
    }
}

Этот код импортирует сертификат, однако, похоже, он игнорирует цепочку.Если я проверяю сертификат в магазине, путь сертификации показывает только:

  • Мой сертификат

Однако, когда я импортирую pfx вручную, он показывает полный путь.Я пропускаю шаг здесь, или я пропускаю какой-то параметр?Может кто-нибудь пролить свет на это?

Ответы [ 4 ]

15 голосов
/ 06 февраля 2012

Вы должны иметь возможность перебирать сертификаты в вашем PFX (и импортировать каждый из них в хранилище сертификатов по вашему выбору), открывая файл PFX как объект X509Certificate2Collection.

Вот документы по X509Certificate2Collection:

http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509certificate2collection.aspx

MSDN предоставляет пример кода на этой странице документации о том, как проверять каждый сертификат в коллекции.

Как только вы знаете CNs / Issuers / другую информациюо каждом сертификате должно быть ясно, к какому хранилищу сертификатов нужно добавить каждый сертификат.Для этого вы можете использовать класс X509Store и перечисление StoreName, чтобы указать, в какое хранилище вы хотите открыть / добавить:

http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.x509store.aspx

http://msdn.microsoft.com/en-us/library/system.security.cryptography.x509certificates.storename.aspx

См. Такжемой ответ на аналогичный вопрос SO:

Как получить сертификаты из файла pfx с помощью c #?

Как упоминалось в одном из последних комментариев к этому ответу, когдапри попытке импортировать сертификат в корневое хранилище текущего пользователя («StoreName.Root» и «StoreLocation.CurrentUser» в качестве имени / местоположения) вы получите всплывающее диалоговое окно с просьбой подтвердить.

Чтобы решить эту проблемуЯ просто добавил немного кода MS UI Automation в свой метод импорта сертификатов, чтобы щелкнуть OK в приглашении.

Или, как говорит комментатор «CodeWarrior» в комментарии к другому ответу SO, чтобы избежать всплывающего диалогового окна, которое выможно попробовать поместить корневой сертификат в хранилище LocalMachine вместо CurrentUser.

Пример кода:

string certPath = <YOUR PFX FILE PATH>;
string certPass = <YOUR PASSWORD>;

// Create a collection object and populate it using the PFX file
X509Certificate2Collection collection = new X509Certificate2Collection();
collection.Import(certPath, certPass, X509KeyStorageFlags.PersistKeySet);

foreach (X509Certificate2 cert in collection)
{
    Console.WriteLine("Subject is: '{0}'", cert.Subject);
    Console.WriteLine("Issuer is:  '{0}'", cert.Issuer);

    // Import the certificate into an X509Store object
}
8 голосов
/ 13 февраля 2012

Для дальнейшего использования я обнаружил другой способ сделать это, используя объект X509Chain:

var cert = new X509Certificate2(pathToCert, password);

X509Chain chain = new X509Chain();
chain.Build(cert);
for (int i = 0; i < chain.ChainElements.Count; i++)
{
   //add to the appropriate store
}
1 голос
/ 08 января 2016

Для тех, кто хочет «в соответствующий магазин» универсальное решение кода

Это то, что я создал с помощью VB, поэтому не должно быть трудным портировать на C #. Я использовал вышеупомянутые посты, чтобы начать, и я полностью NooB в этом.

    Dim certPath = "C:\Users\08353153\Documents\Visual Studio 2015\Projects\WindowsApplication2\WindowsApplication2\bin\Debug\8870-thebigchess.pfx"
    Dim certPass = "eduSTAR.NET"
    Dim Collection As New X509Certificate2Collection
    Collection.Import(certPath, certPass, X509KeyStorageFlags.PersistKeySet)

    Dim certOne As X509Certificate2 = Collection(0)
    Dim certTwo As X509Certificate2 = Collection(2)
    Dim certThree As X509Certificate2 = Collection(1)

    Dim personal As New X509Store(StoreName.My, StoreLocation.LocalMachine)
    personal.Open(OpenFlags.ReadWrite)
    personal.Add(certOne)
    personal.Close()

    Dim trust As New X509Store(StoreName.Root, StoreLocation.LocalMachine)
    trust.Open(OpenFlags.ReadWrite)
    trust.Add(certTwo)
    trust.Close()

    Dim intermed As New X509Store(StoreName.CertificateAuthority, StoreLocation.LocalMachine)
    intermed.Open(OpenFlags.ReadWrite)
    intermed.Add(certThree)
    intermed.Close()
0 голосов
/ 04 февраля 2012

Сертификат X.509 содержит только цепочку, которая связывает его с корневым сертификатом (включая промежуточные органы), но эти сертификаты не содержатся в сертификате. Эта цепочка используется при проверке конечного сертификата (который не является самоподписанным) - он должен приводить к доверенному корневому сертификату. Точнее, открытый ключ каждого ЦС используется для декодирования и проверки хэша для выданного сертификата. Этот процесс повторяется до тех пор, пока не будет получен корневой сертификат. После проверки всей цепочки, если корневой сертификат является доверенным, конечный сертификат также является доверенным. Конечно, этот процесс включает и другие проверки (например, дату начала, дату окончания, список отзыва сертификатов), но я подробно описал только часть, касающуюся использования цепочки.

Итак, вы правильно импортировали «Мой сертификат» вместе с цепочкой в ​​«Корневой сертификат CA» - эта цепочка закодирована в «Мой сертификат», и вы можете подтвердить это, просмотрев его свойства, но эта цепочка является только ссылкой и он не содержит никаких сертификатов «Корневой сертификат CA», «Сертификат организации CA» и «Сертификат организации CA».

Я надеюсь, что это решит вашу проблему, но если это не так, не могли бы вы рассказать о том, чего вы пытаетесь достичь?

...