2009-02-19 10 views
5

Come posso garantire di accedere ai certificati dalla mia SmartCard e non formare il mio negozio di certificati personali in C#? e Come posso rendere il mio RSACryptoProvider per utilizzare la chiave privata del certificato della smart card?Certificati da SmartCard in C#

grazie

Wally

risposta

3

A volte, soprattutto se non si utilizza il nome del contenitore chiave predefinito sulla smart card (consigliato da Microsoft), i certificati non vengono copiati nell'archivio certificati locale. La soluzione è utilizzare crypto api per accedere alla chiave con KP_CERTIFICATE, costruire il certificato dai dati recuperati e assegnargli un nuovo RSACryptoServiceProvider costruito usando il proprio nome del contenitore chiave.

Lo pseudo codice C# segue:

int reti = CryptoApi.CryptGetUserKey(_hprovider, keytype, ref userKey); 

if (reti) 
{ 
    reti =CryptoApi.CryptGetKeyParam(_userKey, KP_CERTIFICATE, ref pbdata, ref pwddatalen, 0); 
} 

if (reti || pwddatalen>0) 
{ 
    byte[] data = new byte[pwddatalen]; 
    ret = CryptoApi.CryptGetKeyParam(_userKey, KP_CERTIFICATE, data, ref pwddatalen, 0); 
    if (ret) 
    { 
     X509Certificate2 c = new X509Certificate2(data); 
     X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser); 
     store.Open(OpenFlags.ReadOnly); 
     X509Certificate2Collection col = store.Certificates.Find(X509FindType.FindByThumbprint, c.Thumbprint, validonly); 
     store.Close(); 

     if (col.Count != 1) 
     { 
      //not found in store - CSP didn't copy it 
      c.PrivateKey = PrivateKey(keytype); 
      return c; 
     } 
     else 
     { 
      return col[0]; 
     } 
    } 
} 


private RSACryptoServiceProvider PrivateKey (KeyType keytype) 
{ 
    CspParameters csparms = new CspParameters(); 
    csparms.KeyContainerName = _containerName; 
    csparms.ProviderName = _provider; 
    csparms.ProviderType = 1; 
    csparms.Flags = CspProviderFlags.UseMachineKeyStore | CspProviderFlags.UseExistingKey; 
    csparms.KeyNumber = (int)keytype; 

    return new RSACryptoServiceProvider(csparms); 
} 
+0

Sono un po 'confuso su quando questo codice sarebbe necessario? Se dici di conoscere la riga dell'oggetto della smart card, la memorizzi per ciascuno dei tuoi utenti al momento della registrazione e quindi memorizzi il certificato nel DB, quindi ogni volta che qualcuno tenta di accedere, confronta il certificato in DB con il certificato fornito in Richiesta .ClientCertificate, giusto? – Dexter

+0

È possibile memorizzare solo parte pubblica del certificato da qualche parte e il confronto tra le parti pubbliche del certificato non è sufficiente a dimostrare il possesso della chiave privata. Pertanto è necessario l'accesso con chiave privata per firmare alcuni dati e provarlo. Il provider di crittografia a volte rende disponibile la chiave privata all'archivio certificati e talvolta no. Nel caso in cui non è questo il modo per ottenerlo. –

+0

C'è un articolo in cui hai trovato questo tipo di codice? Il tuo codice è un po 'incompleto con variabili non dichiarate. Dove c'è un articolo in C# che descrive questo processo di verifica della validità delle chiavi private. Ho sempre pensato che un semplice controllo della certificazione valida utilizzando X509Certificate per verificare se l'hash è un hash valido nel certificato client potrebbe essere sufficiente, ma sì, suppongo che possa essere simulato con un certificato autofirmato. Qualsiasi informazione sarebbe utile. – Dexter

2

Avrete bisogno di passare attraverso il provider di servizi di crittografia (CSP) per il vostro smart card. Su Windows (2000, XP e Vista) ogni volta che si inserisce la smartcard in un lettore di smart card, tutti i certificati su di esso vengono propagati nell'archivio certificati personale. La tua chiave privata rimane sulla tua smart card. Ciò significa che se si utilizza il certificato (ad esempio per firmare digitalmente un'e-mail), viene richiesto di inserire la smart card. Se la tua smart card richiede un PIN ti verrà chiesto di inserirlo. La ragione di ciò è che esiste una posizione in cui le applicazioni possono cercare i certificati utente, l'archivio certificati personale, in modo che le applicazioni non debbano essere riscritte solo per gestire i certificati sulle smartcard.

+0

applicazioni Java possono utilizzare la smart card/certificato senza installare il certificato sul negozio personale. Se non è stato installato in precedenza, le app .NET non sono riuscite a trovare il certificato necessario. –