2011-12-09 9 views
56

sto avendo un problema quando uso il metodo X509Store.Certificates.FindProblemi con X509Store Certificates.Find FindByThumbprint

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

In questo caso il metodo di ricerca restituisce 0 risultati (results.Count == 0), ma se metto il findValue costante il metodo trova il certificato.

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

risposta

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

Credo che si intende il secondo parametro di essere "findValue".

+0

il 2 ° parametro è veramente findValue, – nunofamel

+0

Se questo è il caso, il problema è altrove. Una stringa letterale rispetto a un parametro variabile stringa non si interromperà in questo modo a meno che il contenuto effettivo sia diverso (whitespace? Trailing newline?) – Joe

0

sostituire il codice per trovare il certificato in negozio, come di seguito:

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

Anche il 3 ° param che è certificati di ritorno BOOL solo se il certificato è valido. Quindi assicurati che il tuo certificato sia valido. Se si dispone di un certificato autofirmato o meno quindi basta passare il 3 ° parametro per essere "falso"

+0

Il certificato è valido, perché quando un valore inserito restituisce il metodo 1 valore var results = store .Certificates.Find (findType, "7a6fa503ab57b81d6318a51ca265e739a51ce660", vero); // risultato.Conteggio = 1 :) – nunofamel

+0

Puoi verificare qual è l'Id identificazione personale che viene passato in fase di esecuzione al metodo? – Rajesh

+0

è corretto li metto su Imediate windows, e ha lo stesso valore :( – nunofamel

93

Suppongo di aver copiato l'impronta digitale dalla finestra di dialogo delle informazioni sul certificato di Windows nel codice (o in un file di configurazione se questo è un esempio semplificato). Fastidiosamente, il primo carattere nella casella di testo dell'identificazione rapida è l'invisibile Unicode "left-to-right-mark". Prova a selezionare la citazione della stringa di apertura e il primo carattere dell'identificazione personale, eliminandoli (eliminando anche il carattere invisibile) e digitandoli nuovamente a mano.

Oggi sono stato sottoposto a questo strano comportamento e mi ci è voluto più di un'ora per capirlo. Il modo in cui l'ho visto è stato utilizzando il debugger per controllare le lunghezze e i codici hash di findValue e dello Thumbprint dell'oggetto certificato.

+3

Un modo più semplice di ridigitare è copiare l'identificazione personale dalla finestra di dialogo della console di gestione dei certificati e incollarla in un editor di testo (come Notepad ++), a quel punto il carattere Unicode invisibile apparirà come "?" o qualche altro personaggio ovviamente strano. È quindi possibile annullare questo carattere e copiare la stringa "aggiornata" nel codice/config/casella di testo. – nateirvin

+2

@nateirvin: True (il mio suggerimento di ridigitare a mano è un po 'eccessivo, ed è stato ispirato da quanto ero frustrato a quel punto) - o incollarlo in modalità UTF-8 e attivare la visualizzazione di caratteri nascosti (che è ancora di più interessante perché ti mostra esattamente quale personaggio è). –

+0

Se non si riesce in Visual Studio, eliminare la linea in quanto vi è un carattere di spazio invisibile che non è possibile eliminare singolarmente. – James

1

Questo codice dovrebbe funzionare.

Suppongo di aver copiato questa identificazione personale dalla console di gestione dei certificati. E quel valore copiato contiene un simbolo non leggibile unicode che è invisibile in Visual Studio. Prova a eliminare il primo simbolo invisibile e, se questo è ciò che penso, lo dovrebbe funzionare.

8

Sono caduto vittima di questo. Non solo c'era un carattere Unicode "da sinistra a destra" nella visualizzazione snap-in della console di Windows dell'identificazione personale, ma aveva anche caratteri minuscoli esadecimali, con spazi tra ogni due caratteri. L'output di CertUtil aveva anche caratteri minuscoli e spazi. Per ottenere una corrispondenza, ho dovuto specificare il findValue come una stringa che è stato trasformato per

  1. Rimuovere il carattere speciale che porta,
  2. Rimuovere lo spazio bianco tra i cluster di caratteri,
  3. cambiare tutti i caratteri a maiuscolo.
1

Mi sono imbattuto in questa stessa cosa. Non ho trovato questa risposta da nessuna parte qui, quindi la pubblicherò. Mi sembra che la funzione di ricerca X509Store sia semplicemente piatta e non funzionante. Ho verificato questo con un semplice ciclo per e recuperando manualmente il certificato.

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]; 
      } 
     } 
21

ho avuto lo stesso problema e risolto:

  1. Ho copiato l'impronte digitali da mmc direttamente a VS. Ho confrontato le corde e non ho trovato alcuna differenza.

  2. Controllo della lunghezza con hash.length, c'era una differenza, 41 contro 40.

C'è un Char invisibile aggiunto alla stringa copiandolo su MMC.


Solving:

  1. copia il Fingerprint da MMC per Notepad.exe
  2. copia questa stringa di nuovo
  3. pasta al codice

E 'di lavoro.

33

Ho preso alcune delle risposte qui e le ho combinate in un metodo statico che si occupa della rimozione di caratteri speciali e maiuscole di tutto. Spero che qualcun altro possa usarlo.

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(); 
     } 
    } 
+2

Questo dovrebbe essere accettato come risposta. Funziona perfettamente !! –

+6

Che Regex.Replace dovrebbe essere "[^ \ da-fA-F]" - le thumbprint sono stringhe esadecimali. –

+0

Grazie, Regex ha appena risolto il problema che avevo dopo aver imprecato al codice per mezz'ora. – Frans

0

Ecco la semplice versione del codice per la suggestions- sopra naturalmente, che è funzionato per me

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

Questo mi ha scattato troppo, ho scritto questa funzione per pulire l'identificazione personale quando copiato e incollato da 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]; 
0

Incontro anche questo char Unicode invisibile. Provare ad usare Notepad (Windows 10) in qualche modo non ha funzionato bene neanche per me. Infine, utilizzo PowerShell per ottenere l'impronta digitale pulita:

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

Tanto per il char Unicode.

0

Giusto per farvi sapere che cosa il personaggio invisibile è, vedo l'identificazione personale nell'essere mmc: 75 3a ...

Poi Copio e incollo nel mio vim, vedo il seguente:

< 200e> 75 3a ...

Così dopo aver sbarazzarsi del primo char "< 200e>" e gli spazi in più, andrà tutto bene.