web-dev-qa-db-fra.com

Problèmes liés aux certificats X509Store.Find FindByThumbprint

J'ai un problème lorsque j'utilise la méthode X509Store.Certificates.Find

public static X509Certificate2 FromStore(StoreName storeName, 
          StoreLocation storeLocation, X509FindType findType, string findValue)
{
    X509Store store = new X509Store(storeName, storeLocation);
    store.Open(OpenFlags.ReadOnly);
    try
    {
        //findValue = "7a6fa503ab57b81d6318a51ca265e739a51ce660"
        var results = store.Certificates.Find(findType, findValue, true);

        return results[0];                
    }
    finally
    {
        store.Close();
    }
}

Dans ce cas, la méthode Find renvoie 0 résultats (results.Count == 0), mais si je mets findValue comme constante, la méthode recherche le certificat.

public static X509Certificate2 FromStore(StoreName storeName, 
           StoreLocation storeLocation, X509FindType findType, string findValue)
{
    X509Store store = new X509Store(storeName, storeLocation);
    store.Open(OpenFlags.ReadOnly);
    try
    {         
        //findValue= "7a6fa503ab57b81d6318a51ca265e739a51ce660"
        var results = store.Certificates.Find(findType, 
                              "7a6fa503ab57b81d6318a51ca265e739a51ce660", true);
        return results[0];
    }
    finally
    {
        store.Close();
    }
}
70
nunofamel

Je suppose que vous avez copié-collé l’empreinte numérique de la boîte de dialogue Informations sur les certificats Windows dans votre code (ou dans un fichier de configuration, s’il s’agit d’un exemple simplifié). De manière gênante, le premier caractère de la zone de texte empreinte numérique est le caractère de contrôle invisible Unicode "marque de gauche à droite" . Essayez de sélectionner la citation de la chaîne d'ouverture et le premier caractère de l'empreinte numérique, de les supprimer (ce qui éliminera également le caractère invisible) et de les ressaisir à la main.

J'ai moi-même été victime de ce comportement étrange aujourd'hui et il m'a fallu plus d'une heure pour le comprendre. J'ai finalement compris que c'était en utilisant le débogueur pour vérifier les longueurs et les codes de hachage de findValue et de Thumbprint de l'objet de certificat.

118
Aasmund Eldhuset

J'ai pris certaines des réponses ici et les ai combinées dans une méthode statique qui prend soin de supprimer les caractères spéciaux et les majuscules. Espérons que quelqu'un d'autre puisse l'utiliser.

    public static X509Certificate2 GetCertificate(string thumbprint)
    {
        // strip any non-hexadecimal values and make uppercase
        thumbprint = Regex.Replace(thumbprint, @"[^\da-fA-F]", string.Empty).ToUpper();
        var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);

        try
        {
            store.Open(OpenFlags.ReadOnly);

            var certCollection = store.Certificates;
            var signingCert = certCollection.Find(X509FindType.FindByThumbprint, thumbprint, false);
            if (signingCert.Count == 0)
            {
                throw new FileNotFoundException(string.Format("Cert with thumbprint: '{0}' not found in local machine cert store.", thumbprint));
            }

            return signingCert[0];
        }
        finally
        {
            store.Close();
        }
    }
42
jhilden

J'ai eu le même problème et l'ai résolu:

  1. J'ai copié l'empreinte digitale de mmc directement sur VS. J'ai comparé les cordes et n'ai trouvé aucune différence.

  2. En vérifiant la longueur avec hash.length, il y avait une différence, 41 vs 40.

Il y a un caractère invisible ajouté à la chaîne en le copiant dans mmc.


Résolution:

  1. copier l'empreinte digitale de mmc vers Notepad.exe
  2. copier à nouveau cette chaîne
  3. coller dans votre code

Ça marche.

22
Thomas

Cela m'a aussi fait trébucher, j'ai écrit cette fonction pour nettoyer l'empreinte lorsque copié et collé à partir de MMC:

public string CleanThumbprint(string mmcThumbprint)
    {
        //replace spaces, non Word chars and convert to uppercase
        return Regex.Replace(mmcThumbprint, @"\s|\W", "").ToUpper();
    }

...
        var myThumbprint = CleanThumbprint("‎b3 ab 84 e5 1e e5 e4 75 e7 a5 3e 27 8c 87 9d 2f 05 02 27 56");
        var myCertificate = certificates.Find(X509FindType.FindByThumbprint, myThumbprint, true)[0];
8
Rob C

Je suis victime de cela. Il y avait non seulement un caractère Unicode «de gauche à droite» dans l'affichage enfichable de la console Windows de l'empreinte numérique, mais il contenait également des caractères hexadécimaux minuscules, avec des espaces entre chaque deux caractères. La sortie de CertUtil comportait également des caractères minuscules et des espaces. Pour obtenir une correspondance, je devais spécifier findValue en tant que chaîne transformée en 

  1. Supprimez le caractère spécial principal,
  2. Supprimer les espaces entre les groupes de caractères,
  3. Remplacez tous les caractères par majuscule .
8
Greg

Ce code devrait fonctionner.

Je suppose que vous avez copié cette empreinte numérique à partir de la console de gestion des certificats ..__ Et cette valeur copiée contient un symbole non lisible Unicode invisible dans Visual Studio. Essayez de supprimer le premier symbole invisible et si c'est ce que je pense, cela devrait fonctionner.

2
Dmitry Dyachkov

Je suis tombé sur la même chose. Je n'ai trouvé cette réponse nulle part ici, alors je vais la poster. Il me semble que la fonction de recherche X509Store était simplement plate et ne fonctionnait pas. J'ai vérifié cela par une simple boucle for et en récupérant le certificat manuellement. 

  X509Store store = new X509Store(StoreName.Root,StoreLocation.LocalMachine);
        store.Open(OpenFlags.ReadOnly);
        X509Certificate cert = new X509Certificate();
        for (int i = 0; i < store.Certificates.Count; i++)
        {
            if (store.Certificates[i].SerialNumber == "XXXX")
            {
                cert = store.Certificates[i];
            }
        }
1
vikingben

Remplacez le code pour trouver votre certificat dans le magasin comme ci-dessous:

var results = store.Certificates.Find(findType, findValue, true); 

De plus, le 3ème paramètre qui est bool ne renvoie des certificats que si le certificat est valide. Assurez-vous donc que votre certificat est valide. Si vous avez un certificat auto-signé ou presque, passez simplement le 3ème paramètre pour qu'il soit "faux"

1
Rajesh

Pour que vous sachiez quel est le caractère invisible, je vois l'empreinte dans le mmc: 75 3a ...

Puis je le copie et le colle dans mon vim, je vois ce qui suit:

<200e> 75 3a ...

Ainsi, après vous être débarrassé du premier caractère "<200e>" et des espaces supplémentaires, tout ira bien.

0
iefgnoix

Je rencontre aussi ce caractère Unicode invisible. Essayer d'utiliser Notepad (Windows 10) n'a pas fonctionné pour moi non plus. Enfin, j'utilise PowerShell pour obtenir l'hex propre d'empreinte numérique:

PS C:\> $tp= (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object {$_.Subject -match "mycert"}).Thumbprint;
PS C:\> $tp

Voilà pour le caractère Unicode.

0
Riza Marhaban

Voici la version simple du code pour les suggestions ci-dessus qui sont travaillées pour moi

 private X509Certificate2 GetCertificate()
    {
        var certStore = new X509Store("my");
        certStore.Open(OpenFlags.ReadOnly);
        try
        {
            const string thumbprint = "18 33 fe 3a 67 d1 9e 0d f6 1e e5 d5 58 aa 8a 97 8c c4 d8 c3";
            var certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint,
            Regex.Replace(thumbprint, @"\s+", "").ToUpper(), false);
            if (certCollection.Count > 0)
                return certCollection[0];
        }
        finally
        {
            certStore.Close();
        }
        return null;
    }
0
Jay
var results = store.Certificates.Find(findType, findType, true);

Je pense que vous voulez dire que le 2ème paramètre est "findValue". 

0
Joe