2009-02-19 14 views
5

Wie kann ich sicherstellen, dass ich auf die Zertifikate von meiner SmartCard zugreife und nicht meinen persönlichen Zertifikatspeicher in C# erstelle? und Wie kann ich meinen RSACryptoProvider so einrichten, dass er den privaten Schlüssel meines Smartcard-Zertifikats nutzt?Zertifikate von SmartCard in C#

dank

Wally

Antwort

3

Manchmal werden die Zertifikate nicht in den lokalen Zertifikatspeicher kopiert, insbesondere wenn Sie nicht den Standardschlüsselbehälternamen auf der Smartcard verwenden (von Microsoft empfohlen). Die Lösung besteht darin, crypto api zu verwenden, um mit KP_CERTIFICATE auf den Schlüssel zuzugreifen, ein Zertifikat aus den abgerufenen Daten zu konstruieren und ihm einen neuen RSACryptoServiceProvider zuzuweisen, der mit Ihrem eigenen Schlüsselcontainernamen erstellt wurde.

Der Pseudo-C# -Code folgt:

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

Ich bin ein bisschen verwirrt, wenn ein solcher Code benötigt würde? Wenn Sie die Betreffzeile der Smartcard kennen, speichern Sie diese für jeden Ihrer Benutzer bei der Registrierung und speichern das Zertifikat in der DB. Jedes Mal, wenn sich jemand anmeldet, wird das Zertifikat in der Datenbank mit dem in Request angegebenen Zertifikat verglichen .ClientZertifikat, oder? – Dexter

+0

Sie können den öffentlichen Teil des Zertifikats nur irgendwo speichern - und der Vergleich öffentlicher Teile des Zertifikats reicht nicht aus, um den Besitz des privaten Schlüssels nachzuweisen. Daher benötigen Sie einen privaten Schlüsselzugriff, um einige Daten zu signieren und dies zu beweisen. Der Crypto-Provider stellt den privaten Schlüssel zum Zertifikatsspeicher manchmal automatisch und manchmal nicht zur Verfügung. Für den Fall, dass dies nicht der Fall ist. –

+0

Gibt es einen Artikel, in dem Sie diese Art von Code gefunden haben? Ihr Code ist bei nicht deklarierten Variablen unvollständig. Wo gibt es einen C# -Artikel, der diesen Prozess der Überprüfung der Gültigkeit von privaten Schlüsseln beschreibt. Ich habe immer eine einfache Überprüfung der gültigen Zertifizierung mit X509Certificate angenommen, um zu überprüfen, ob der Hash ein gültiger Hash im Client-Zertifikat ist, aber genug, ja, ich nehme an, dass er mit einem selbstsignierten Zertifikat gefälscht werden kann. Jede Information wäre hilfreich. – Dexter

2

Sie benötigen, um Ihre Cryptographic Service Provider (CSP) für die Smartcard zu gehen. Unter Windows (2000, XP und Vista) Jedes Mal, wenn Sie Ihre Smartcard in einen Smartcard-Leser einlegen, werden alle Zertifikate darauf in Ihren persönlichen Zertifikatspeicher übertragen. Ihr privater Schlüssel bleibt auf Ihrer Smartcard. Das heißt, wenn Sie Ihr Zertifikat verwenden (z. B. um eine E-Mail digital zu signieren), werden Sie aufgefordert, Ihre Smartcard einzulegen. Wenn Ihre Smartcard eine PIN erfordert, werden Sie aufgefordert, sie einzugeben. Der Grund dafür ist, dass Anwendungen nur einen Speicherort für Benutzerzertifikate haben, also Ihren persönlichen Zertifikatspeicher, sodass Anwendungen nicht nur für die Verarbeitung von Zertifikaten auf Smartcards neu geschrieben werden müssen.

+0

Java-Anwendungen, die Smartcard/Zertifikat Zertifikat ohne Installation auf privaten Speicher verwenden können. Wenn es nicht zuvor installiert wurde, konnten .NET-Apps das erforderliche Zertifikat nicht finden. –