9 Stimmen

Beste Methode zum Signieren von Daten in Webformularen mit Benutzerzertifikat

Wir haben eine C#-Webanwendung, bei der die Benutzer eine Verbindung mit einem digitalen Zertifikat herstellen, das in ihren Browsern gespeichert ist.

Anhand der Beispiele, die wir gesehen haben, ist es einfach, die Identität des Benutzers zu überprüfen, sobald wir SSL aktivieren, da wir mit Request.ClientCertificate auf die Felder im Zertifikat zugreifen können, um den Namen des Benutzers zu überprüfen.

Wir wurden jedoch auch gebeten, die vom Benutzer übermittelten Daten (einige einfache Felder und eine Binärdatei) zu signieren, damit wir zweifelsfrei nachweisen können, welcher Benutzer jeden Datensatz in unsere Datenbank eingegeben hat.

Unser erster Gedanke war, eine kleine Textsignatur mit den Feldern (und, wenn möglich, dem md5-Wert der Datei) zu erstellen und sie mit dem privaten Schlüssel des Zertifikats zu verschlüsseln, aber...

Soweit ich weiß, können wir nicht auf den privaten Schlüssel des Zertifikats zugreifen, um die Daten zu signieren, und ich weiß nicht, ob es eine Möglichkeit gibt, die Felder im Browser zu signieren, oder ob wir keine andere Möglichkeit haben, als ein Java-Applet zu verwenden. Und wenn letzteres der Fall ist, wie würden wir es tun (Gibt es ein Open-Source-Applet, das wir verwenden können? Wäre es besser, wenn wir selbst eines erstellen?)

Natürlich wäre es besser, wenn es eine Möglichkeit gäbe, die auf dem Server empfangenen Felder zu "signieren", indem wir die Daten verwenden, auf die wir über das Zertifikat des Benutzers zugreifen können. Aber wenn nicht, jede Info über den besten Weg, um das Problem zu lösen, wäre zu schätzen.

8voto

Sasha Punkte 1928

Ich schlage Ihnen vor, ein Java-Applet zu verwenden. Dieser Ansatz ist für alle Browser einheitlich. Wir verwenden ihn in unseren Projekten. Um die Benutzerdaten zu signieren, müssen Sie die JCA-API verwenden ( http://download.oracle.com/javase/1.4.2/docs/guide/security/CryptoSpec.html#Signature ). Außerdem müssen Sie das Problem des Zugriffs auf den Windows-Zertifikatspeicher von Java aus lösen.

Sie können das Problem auf diese Weise lösen:

KeyStore keystore = KeyStore.getInstance("Windows-MY", "SunMSCAPI");

keystore.load(null, null);

HashMap<String,String> userPublicKeys = new HashMap<String,String>();

Enumeration<String> aliasesEnum = keystore.aliases();

if (!aliasesEnum.hasMoreElements())
    throw new Exception("No certificate!");

// list through windows personal store
while (aliasesEnum.hasMoreElements()) 
{
   String alias = aliasesEnum.nextElement();

   boolean isKey = keystore.isKeyEntry(alias);

   if (isKey)
   {
       BASE64Encoder encoder = new BASE64Encoder();
       encoder.encode(keystore.getCertificate(alias).getEncoded());

       userPublicKeys.put(alias, encoder.encode(keystore.getCertificate(alias).getEncoded()));
       System.out.println("Entry alias: " + alias); 
   }

   // sign
   PrivateKey privateKey = (PrivateKey) keystore.getKey(alias,null);           

   Provider provider = keystore.getProvider();
   // data to signed
   byte[] data ="test data".getBytes();
   // Signing the data
   Signature sig = Signature.getInstance("SHA1withRSA", provider);
   sig.initSign(privateKey);

   sig.update(data);
   byte[] signature = sig.sign();

   System.out.println(ByteArrayToFromHexDigits.bytesToHexString(signature).toUpperCase());
}

2voto

Scott Chamberlain Punkte 120610

Sie müssen Ihre Rechtsabteilung fragen, ob dies eine ausreichend starke "Signierung" ist, aber bei jeder Übermittlung der Felder muss der Server die Feldwerte und den Fingerabdruck des Zertifikats aus dem Handshake des Client-Zertifikats aufzeichnen. Ja, dies ist "fälschbar", da jeder, der den Fingerabdruck kennt, einen gefälschten Datensatz in der Datenbank erstellen könnte, aber mit einer angemessenen Datenbanksicherheit können Sie diesen Angriffsvektor beseitigen und haben eine Aufzeichnung darüber, wer was gepostet hat (da Sie den Fingerabdruck des Client-Zertifikats bei einer zweiseitigen Authentifizierung von SSL nicht fälschen können).

1voto

Richard Punkte 103159

können wir nicht auf den privaten Schlüssel des Zertifikats zugreifen, um die Daten zu signieren,

Wäre dies nicht der Fall, könnte sich der Server das Zertifikat selbst merken und es verwenden, um sich bei der Nutzung anderer Dienste als der echte Client auszugeben.

D. h., die Verwendung von Client-Zertifikaten zur Authentifizierung des Clients würde vollständig außer Kraft gesetzt.

und ich weiß nicht, ob es eine Möglichkeit gibt, die Felder im Browser zu signieren,

Wie wäre es, diese Frage mit geeigneten clientseitigen Tags (z. B. JavaScript, Browser) zu stellen, um die richtige Zielgruppe zu erreichen? (Ich bin mir sicher, dass dies auch mit einer Browser-Erweiterung oder einem ActiveX-Objekt möglich wäre, aber das schafft seine eigenen Probleme).

1voto

VladV Punkte 9703

Es gibt eine JavaScript-Methode crypto.signText, die es erlaubt, einen beliebigen Text mit einem Client-Zertifikat zu signieren. Hier sind einige docs y ein Beispiel für ein unterzeichnetes Formular . Es scheint, dass derzeit nur Firefox dies unterstützt.

Für den IE gibt es das CAPICOM-ActiveX-Objekt (erhältlich als Download von MS). Hier ist ein Beispiel für seine Verwendung.

Ich bin mir nicht sicher, ob diese Funktionen in verschiedenen Browsern und Betriebssystemversionen unterstützt werden, Sie müssen dies wahrscheinlich für Ihre Konfiguration überprüfen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X