2009-02-17 14 views
9

Ho un servizio Web ASP.NET che riceve una matrice di byte che rappresenta il contenuto di un file .pfx contenente un certificato X.509. Il codice lato server utilizza il costruttore System.Security.Cryptography.X509Certificate2 per caricare il certificato dal byte:Perché a volte X509Certificate2 non riesce a creare da un blob?

X509Certificate2 native_cert = new X509Certificate2(
       pkcs12_buf /*byte array*/, 
       password, 
       X509KeyStorageFlags.PersistKeySet | 
       X509KeyStorageFlags.Exportable 
      ); 

A seconda di chi il mio processo di servizio è in esecuzione come, questa chiamata sia successo, o non riuscire con un'eccezione "errore interno" . L'ultima chiamata nello stack di eccezioni è a X509Utils._LoadCertFromBlob, che è il codice non gestito in mscore.dll.

Questo codice ha esito positivo quando viene eseguito da un'applicazione console in un accesso interattivo utilizzando le credenziali dell'account del servizio. Non funziona quando è in esecuzione con w3wp.exe in un pool di applicazioni che utilizza le credenziali dell'account del servizio. La modifica dell'identità del pool di applicazioni su un amministratore risolve il problema, quindi deve trattarsi di un problema di privilegi, ma non ho idea di quale privilegio potrebbe essere necessario per questo. Il codice non tocca né il filesystem né gli archivi di certificati di Windows.

[UPDATE: Maggiori informazioni]
Questo errore viene visualizzato nel registro eventi di Windows:

*Cryptographic Parameters:* 
**Provider Name:** Microsoft Software Key Storage Provider 
**Algorithm Name:** Not Available. 
**Key Name:** {E182E13B-166D-472A-A24A-CBEF0808E9ED} 
    **Key Type:** User key. 

*Cryptographic Operation:* 
**Operation:** Open Key. 
    **Return Code:** 0x2 

Tutte le idee?

risposta

8

Ho appena trovato la soluzione a questo uno io:

X509KeyStorageFlags flags = X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.MachineKeySet; 

X509Certificate2 cert = new X509Certificate2(pkcs12_buf, password, flags); 

Il trucco è quello di utilizzare il flag di keystore locale MachineKeySet anziché il keystore del profilo utente, che è l'impostazione predefinita se non si specifica un percorso alternativo. Poiché l'identità del processo ASP.NET non carica l'archivio del profilo utente, non è possibile accedere all'archivio quando si importa un certificato a livello di codice, ma è possibile accedere all'archivio della macchina.

Penso che PersistKeySet tenga semplicemente la chiave privata caricata, ma non sono sicuro di quello che fa, è necessario se è necessario accedere alla chiave privata per qualche motivo.

+0

Perché il contesto utente ASP.Net in esecuzione non ha accesso al proprio archivio? (Questo ha risolto il mio problema - era un classico "Ma funziona sulla mia macchina di sviluppo! Solo curioso sul ragionamento.) – DFTR

2

Prova concedere le autorizzazioni di account ASP.NET nella seguente cartella: C:\Documents And Settings\All Users\Microsoft\Crypto\RSA\MachineKeys\ (può variare a seconda dell'ambiente)

+0

Penso che tu sia sulla strada giusta, ma sembra che non stia cercando di accedere al filesystem. L'account che riesce accede a Microsoft \ Crypto \ RSA sotto il profilo personale dell'utente (non AllUsers). Quello che fallisce non sta nemmeno cercando di accedere al filesystem, secondo procmon. – jlew

+0

Questa modifica del permesso ha funzionato per me su Win2k8. Mi ha salvato un sacco di tempo per il debugging. Grazie! – CodingWithSpike

Problemi correlati