2015-02-27 21 views
7

Di fronte a un problema davvero strano X509Certificate2.Verify() restituisce false per un certificato valido. Forse qualcuno ha già affrontato questo strano scenario prima e può far luce su di esso.X509Certificate2.Verify() restituisce false sempre

Sto usando openssl per generare certificati client a scopo di test. Creo una CA radice e generi un certificato client basato su tale CA radice e aggiungo la CA radice alla relativa catena.

Carico la CA radice e il Cert client nell'archivio certificati locale e sembra ok, ma quando lo carico dal mio codice NUnit per testare X509Certificate2.Verify() restituisce sempre false.

enter image description here

ecco il codice per caricare il Cert dal negozio:

 X509Store store = new X509Store(StoreName.My); 
     string thumbprint = "60 d1 38 95 ee 3a 73 1e 7e 0d 70 68 0f 2d d0 69 1e 9a eb 72"; 
     store.Open(OpenFlags.ReadOnly); 
     var mCert = store.Certificates.Find(
           X509FindType.FindByThumbprint, 
           thumbprint, 
           true 
          ).OfType<System.Security.Cryptography.X509Certificates.X509Certificate>().FirstOrDefault(); 
     if(mCert != null) 
     { 
      var testClientCert = new X509Certificate2(mCert); 
     } 

Ecco il Cert client che ho appena generato: (l'url CRL è accessibile dalla mia macchina locale correttamente)

-----BEGIN CERTIFICATE----- 
MIIC7jCCAlegAwIBAgIBATANBgkqhkiG9w0BAQUFADBtMR0wGwYDVQQKExRWaXRh 
bEhlYWx0aCBTb2Z0d2FyZTElMCMGA1UECxMcVml0YWxIZWFsdGggU29mdHdhcmUg 
Um9vdCBDQTElMCMGA1UEAxMcVml0YWxIZWFsdGggU29mdHdhcmUgUm9vdCBDQTAe 
Fw0xNTAyMjcwODQ2MzNaFw0xNjAyMjcwODQ2MzNaMEUxHTAbBgNVBAoTFFZpdGFs 
SGVhbHRoIFNvZnR3YXJlMREwDwYDVQQLEwhQbGF0Zm9ybTERMA8GA1UEAxMIVGVz 
dFVzZXIwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOkfyjX0PSnRYrBbCC8u 
rw7IiFdAUj6frPKEmt0TLAR/4g+NazKdGjRRqxE9mNwX/2zGhIcucfGDVwPtOtiV 
opicQEzGiSQkvAc+473MN5D6j3XtBYblALMeMyEYoh3LnHO4K+6kV6XE4BXV/2lV 
mAVgXGkZzaayd40DLvg48vPlAgMBAAGjgcUwgcIwCQYDVR0TBAIwADARBglghkgB 
hvhCAQEEBAMCB4AwCwYDVR0PBAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMCMDEG 
CWCGSAGG+EIBDQQkFiJPcGVuU1NMIENlcnRpZmljYXRlIGZvciBTU0wgQ2xpZW50 
ME0GA1UdHwRGMEQwQqBAoD6GPGh0dHA6Ly9wbGF0Zm9ybWRhc2hib2FyZC5ubC52 
aXRhbGhlYWx0aC5sb2NhbC9wb3J0YWwvY3JsLmNybDANBgkqhkiG9w0BAQUFAAOB 
gQBXYSmZaVu6vnyl94SO4qpNOutsUm4p7fQHehljhZ+aRrXE10rivWCt4g0k961E 
PDsp4J0DR6uth6et42pBp8v2gFIGSQY/F7NhmOAsOJvM7z0oIBxMLcclIDTygbRp 
KjZZpNjvf+YJasbidosiL4VSeRiCZ+HPzvKDb3wNeafoZA== 
-----END CERTIFICATE----- 

E qui è il file CRL che ottiene download quando accedo dal browser:

-----BEGIN X509 CRL----- 
MIIBMjCBnDANBgkqhkiG9w0BAQUFADBtMR0wGwYDVQQKExRWaXRhbEhlYWx0aCBT 
b2Z0d2FyZTElMCMGA1UECxMcVml0YWxIZWFsdGggU29mdHdhcmUgUm9vdCBDQTEl 
MCMGA1UEAxMcVml0YWxIZWFsdGggU29mdHdhcmUgUm9vdCBDQRcNMTQwODA3MTQz 
OTIyWhcNMTQwOTA2MTQzOTIyWjANBgkqhkiG9w0BAQUFAAOBgQA8MSxAorbxpdDm 
1IA2Aqjb/OkZydua1Tm5k5KtHknI4zyYPZb3GzO0eRygpKBSAqtYkxDI6eCv6xgf 
+anXT56md+cPGZ+2YvSicxqwP2GL2kymc9mVMTiQieioS1/7apjCIjZEgWxqf3Up 
zvy/kNQRg3lII8hYu0idGs9byKZJFQ== 
-----END X509 CRL----- 
+0

Ci sono alcune domande relative a questo, come questo: http://stackoverflow.com/questions/1277791/x509certificate2-validation-on-web- servizio Hai provato qualcuno di questi ancora? – weston

+0

@weston Sì, davvero. Ho controllato il seguente link che sembra essere il mio, http://stackoverflow.com/questions/10137208/x509certificate2-verify-method-always-return-false-for-the-valid-certificate?rq=1 ma poi posso accedere all'URL CRL nel mio client cert bene dal browser e sto usando i test di Nunits che funzionano con l'account utente Windows locale che ho usato per installare Cert e il suo RootCA nell'archivio Cert corrente per questo utente Windows . – Deb

+0

per favore, esportare questo certificato in un file e mostrarci l'output del comando certutil: 'certutil -verify -urlfetch \ file.cer'. – Crypt32

risposta

13

Secondo la documentazione X509Certificate2.Verify

Questo metodo crea una semplice catena per il certificato e applica il criterio base per quella catena. Se sono necessarie ulteriori informazioni su un errore, convalidare il certificato direttamente utilizzando l'oggetto X509Chain.

Perciò vorrei cercare di costruire la catena utilizzando questo codice (sostituire il metodo Login con la propria implementazione, stavo usando Console.Writeline)

X509Chain chain = new X509Chain(); 

try 
{ 
    var chainBuilt = chain.Build(testClientCert); 
    Log(string.Format("Chain building status: {0}", chainBuilt)); 

    if (chainBuilt == false) 
     foreach (X509ChainStatus chainStatus in chain.ChainStatus) 
      Log(string.Format("Chain error: {0} {1}", chainStatus.Status, chainStatus.StatusInformation)); 
} 
catch (Exception ex) 
{ 
    Log(ex.ToString()); 
} 

Questo codice vi dirà il motivo per cui il certificato potrebbe non essere verificato Se è necessario adattare la politica catena quindi impostare chain.ChainPolicy proprietà cioè

chain.ChainPolicy = new X509ChainPolicy() 
{ 
    RevocationMode = X509RevocationMode.NoCheck, 
    VerificationFlags = X509VerificationFlags.IgnoreNotTimeValid, 
    UrlRetrievalTimeout = new TimeSpan(0, 1, 0) 
}; 
+0

Sì, vero. Ma prima voglio solo fare un controllo di base se il certificato è valido e poi andare a controllare l'intera catena.Non voglio perdere tempo a controllare l'intera catena (che a proposito può essere molto grande nel mio caso) prima che la verifica di base passi sul certificato, il che credo sia un caso d'uso abbastanza semplice e valido. – Deb

+1

Questo codice mi ha aiutato a capire perché Verify() restituiva false. Il chainStatus.StatusInformation ha restituito quanto segue: "La funzione di revoca non è stata in grado di controllare la revoca del certificato." Nel tuo caso, lo stato potrebbe essere diverso, ma credo che il codice sopra riportato sia utile per la risoluzione dei problemi. – user3308241

+1

@Deb Verify crea l'intera catena, ma la butta via. Puoi anche costruirlo da solo (a condizione che tu lo disponga (4.6) o chiamare Reset su di esso (altro) quando hai finito). – bartonjs