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);
}
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
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. –
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