Как программно импортировать pfx с цепочкой сертификатов в хранилище сертификатов?

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

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

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

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 ответов


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

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

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

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

Как только вы узнаете информацию CNs/Issuers/other о каждом сертификате, должно быть ясно, в какое хранилище сертификатов нужно добавить каждый. Для этого вы можете использовать класс 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 в мой метод импорта сертификатов, нажмите OK в приглашении.

или, как комментатор "CodeWarrior" говорит в комментарии другого SO answer, чтобы избежать всплывающего диалога, вы можете попробовать поместить корневой сертификат в 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
}

для дальнейшего использования я обнаружил другой способ сделать это, используя объект 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
}

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

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

    Dim certPath = "C:\Users353153\Documents\Visual Studio 2015\Projects\WindowsApplication2\WindowsApplication2\bin\Debug70-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()

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

таким образом, вы правильно импортировали "мой сертификат" вместе с цепочкой в "корневой сертификат CA" - эта цепочка закодирована в "моем сертификате", и вы можете подтвердить это просмотр его свойств, но эта цепочка является только ссылкой и не содержит сертификатов "корневой сертификат CA", "сертификат организации CA" и "сертификат организации 2 CA".

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