web-dev-qa-db-fra.com

Comment importer par programme un pfx avec une chaîne de certificats dans le magasin de certificats?

J'essaie d'importer par programme un certificat X509 (pfx/PKCS # 12) dans le magasin de certificats de mon ordinateur local. Ce certificat particulier a une chaîne de certificats, le chemin de certification ressemble à ceci:

  • Certificat racine CA
    • Certificat d'organisation CA
      • Certificat d'organisation 2 CA
        • Mon certificat

Le code que j'utilise ressemble à ceci:

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

Ce code importe le certificat, mais il semble ignorer la chaîne. Si je vérifie le certificat dans le magasin, le chemin de certification indique uniquement:

  • Mon certificat

Cependant, lorsque j'importe le pfx manuellement, il affiche le chemin complet. Est-ce que je saute une étape ici ou est-ce qu'il me manque un paramètre? Quelqu'un peut-il nous éclairer à ce sujet?

18
Edwin de Koning

Vous devriez pouvoir parcourir les certificats de votre PFX (et les importer dans le magasin de certificats de votre choix) en ouvrant le fichier PFX en tant qu'objet X509Certificate2Collection.

Voici la documentation sur X509Certificate2Collection:

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

MSDN fournit un exemple de code dans cette page de documentation sur la façon d'inspecter chaque certificat de la collection.

Une fois que vous connaissez les CN, les émetteurs ou d'autres informations sur chaque certificat, vous devez indiquer clairement dans quel magasin de certificats chacun doit être ajouté. Pour cela, vous pouvez utiliser la classe X509Store et l'énumération StoreName pour spécifier le magasin dans lequel vous souhaitez ouvrir/ajouter:

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

Voir aussi ma réponse à une question similaire SO:

Comment récupérer des certificats d'un fichier pfx avec c #?

Comme mentionné dans l'un des derniers commentaires sur cette réponse, lorsque vous essayez d'importer un certificat dans le magasin racine de l'utilisateur actuel ("StoreName.Root" et "StoreLocation.CurrentUser" en tant que nom/emplacement), une boîte de dialogue contextuelle vous demandant vous à confirmer.

Pour résoudre ce problème, je viens d'ajouter un petit code MS UI Automation à ma méthode d'importation de certificat, en cliquant sur OK dans l'invite.

Ou, comme le commentateur "CodeWarrior" l'indique dans le commentaire de l'autre SO, pour éviter la boîte de dialogue contextuelle, vous pouvez essayer de placer le certificat racine dans le magasin LocalMachine au lieu de CurrentUser.

Exemple de code:

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
}
14
Bill Agee

Pour référence future, j'ai découvert une autre manière de procéder, en utilisant l'objet 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
}
7
Edwin de Koning

Pour tous ceux qui veulent "au magasin approprié" code solution générique

C’est ce que j’ai créé avec VB et je ne devrais donc pas avoir trop de mal à le porter en C #. J'ai utilisé les messages ci-dessus pour me lancer et je suis un NooB total à ce sujet. 

    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()
1
Clarkey

Un certificat X.509 contient uniquement une chaîne qui le relie au certificat racine (y compris les autorités intermédiaires), mais ces certificats ne sont pas contenus dans le certificat. Cette chaîne est utilisée lorsqu'un certificat de fin (qui n'est pas auto-signé) est validée. Elle doit conduire à un certificat racine approuvé. Plus précisément, la clé publique de chaque autorité de certification est utilisée pour décoder et vérifier le hachage d'un certificat émis. Ce processus est répété jusqu'à ce que le certificat racine soit atteint. Une fois que toute la chaîne est vérifiée, si le certificat racine est approuvé, le certificat de fin l'est également. Bien sûr, le processus inclut également d'autres validations (telles que la date de début, la date de fin, la liste de révocation de certificats, par exemple), mais je n'ai détaillé que la partie liée à l'utilisation de la chaîne.

Donc, vous avez correctement importé "Mon certificat" avec la chaîne dans "Certificat racine" - cette chaîne est codée dans "Mon certificat" et vous pouvez le confirmer en affichant ses propriétés, mais cette chaîne n'est qu'un lien et elle ne le fait pas. contient l'un des certificats "CA de certificat racine", "CA de certificat d'organisation" et "CA de certificat d'organisation 2".

J'espère que cela résoudra votre problème, mais si ce n'est pas le cas, pourriez-vous être plus précis sur ce que vous essayez d'accomplir?

0
andrei m