Wie kann man aus einer kurzen Passphrase sicher ein asymmetrisches Schlüsselpaar generieren?

  • Hintergrundinfo:
    Ich plane, einen Dateiserver zu erstellen, mit dem Dateien verschlüsselt und hochgeladen werden können. Um die Daten vor jeglicher Form von Hacking zu schützen, möchte ich den für eine Datei verwendeten Verschlüsselungsschlüssel ($ K $) nicht kennen. Daher muss der Benutzer $ K $ asymmetrisch verschlüsseln und auch senden. Der Grund für diese doppelte Verschlüsselung ist, dass Sie weiterhin (einzelne!) Dateien für andere Konten freigeben können, indem Sie $ K $ auch mit den öffentlichen Schlüsseln dieser Benutzer verschlüsseln.

    Mein Problem ist: Wie kann ein Benutzer einen öffentlichen und einen privaten Schlüssel erhalten, ohne dass der Server den privaten Schlüssel und speichert / kennt, ohne dass sich der Benutzer eine Passphrase mit 250 Hex-Zeichen merken muss?

    Frage:
    Gibt es eine Möglichkeit, ein Schlüsselpaar von einem Kennwort abzuleiten, wie es PBKDF-2 für symmetrische Verschlüsselung tut?
    Vorschläge für eine einfachere Neuordnung der kryptographischen Schritte sind ebenfalls erwünscht.

    Alternativ:
    Es ist auch möglich Verschlüsseln Sie den privaten Schlüssel mit einem von PBKDF angewendeten Kennwort und speichern Sie es auf dem Server, aber ich möchte die Dinge einfach halten. ;)

    Hinweis: An diesem Punkt ist es mir egal, ob RSA, ECC oder ein obskures Kryptografieschema erforderlich ist.

    07 July 2012
    David Cary
3 answers
  • Das Beste, auf das Sie hoffen können, ist Folgendes:

    1. Sie leiten das Passwort in ein "ausreichend großes" (z 128 Bit) geheimer Schlüssel $ K $ mit einer Schlüsselableitungsfunktion wie PBKDF2 . Es gibt einige Details, auf die Sie achten sollten (siehe unten).

    2. Sie verwenden den geheimen Schlüssel $ K $ als Startwert für eine Pseudorandom Number Generator . Der PRNG ist deterministisch (der gleiche Ausgangswert weist dieselbe Ausgabesequenz auf) und erzeugt Zufallsbits.

    3. Sie verwenden den PRNG im Schlüsselpaar-Generierungsalgorithmus für jeden beliebigen asymmetrischen Algorithmus, den Sie möchten benutzen. Dieser Schritt ist für diskrete Logarithmus-basierte Algorithmen wie DSA, ElGamal, Diffie-Hellman und deren elliptische Kurvenvarianten billig und einfach, vorausgesetzt, die Gruppenparameter sind im Voraus bekannt (z. B. ist er in allen relevanten Softwarekomponenten, die Sie verwenden, fest codiert machen ECDSA / ECDH mit der standardmäßigen elliptischen P-256-Kurve, die durch NIST definiert wird ). Für RSA ist dies weniger günstig und einfach, da der Schlüsselerzeugungsprozess die Generierung von Zufallszahlen erfordert, bis Primzahlen erreicht werden. Dies ist immer noch möglich.

    Da diese Prozedur deterministisch ist (für ein gegebenes Quellkennwort), können Sie es jedes Mal erneut ausführen Ich brauche den privaten Schlüssel.


    Nun besteht das Problem mit Passwörtern darin, dass sie aus dem relativ kleinen und uneinheitlichen Bereich von "Dingen" stammen, die in den Verstand eines durchschnittlichen Benutzers passen ". Sie sind anfällig für eine umfassende Suche, die für Kennwörter traditionell als Wörterbuchangriff bezeichnet wird. Es gibt drei generische Wege, um mit diesem Problem fertig zu werden:

    • Lassen Sie den Angreifer keine Daten lernen, die ihm erlauben, zu lernen eine Passwort-Schätzung bestätigen. Im üblichen Kontext des Speicherns von Passwort hashes auf einem Server zur Benutzerauthentifizierung bedeutet dies, dass Angreifer nicht in der Lage sein sollen, die Datenbank zu lesen. Aus diesem Grund haben Unix-ähnliche Systeme vor etwa 15 Jahren auf Schattenkennwörter gewechselt. Sie möchten weiterhin Hash-Kennwörter speichern und die beiden anderen Schutzfunktionen verwenden, da in der realen Welt ein unerlaubter Nur-Lese-Zugriff erfolgt.

    • Verwenden Sie eine konfigurierbar langsame Tastenableitungsfunktion. Dadurch werden Wörterbuchangriffe proportional langsamer - bei normalem Gebrauch jedoch um denselben Faktor. Aus diesem Grund enthalten KDF wie PBKDF2 oder bcrypt einen Iterationszähler. Sie möchten diesen Wert auf den höchsten Wert erhöhen, der für Ihre Benutzer noch tolerierbar ist.

    • Verwenden Sie einen Salt , um einen Angriff zu verhindern < em> Parallelität . Beim Parallelismus geht es darum, N -Kennwörter (nicht notwendigerweise gleichzeitig) für weniger als N mal die Kosten eines Angriffs anzugreifen (vorberechnete Tabellen sind eine Art Parallelismus). Das Salz ist ein öffentliches Datenelement, das als Variation des KDF fungiert. Dies ist gleichbedeutend damit, dass es viele verschiedene KDF gibt, und das Salt sagt, welche Sie verwenden.

    In Ihrem Szenario verfügen Sie nicht über den ersten Schutz: Der resultierende öffentliche Schlüssel ist von Natur aus öffentlich und kann daher für Angriffe im Offline-Wörterbuch verwendet werden. Der Angreifer muss nur mögliche Passwörter ausprobieren, bis er denselben öffentlichen Schlüssel findet. Das ist wesentlich für das, was Sie erreichen wollen.

    Der dritte Schutz (das Salz) könnte sich auch als schwierig erweisen. Das Salz muss nicht geheim sein, aber es muss ein gewisses Maß an Integrität haben. Wo das Salz gespeichert wird, muss der Benutzer, der seinen privaten Schlüssel neu berechnen möchte, mit angemessener Sicherheit davon überzeugt sein, dass er das richtige Salz verwendet (andernfalls berechnet er den falschen privaten Schlüssel). Abhängig vom Nutzungsszenario kann ein solcher Speicherplatz möglicherweise nicht einfach sein. Ein Teil

    15 January 2012
    Thomas Pornin
  • Ein gängiger Ansatz besteht darin, den privaten Schlüssel mit einem aus einer Passphrase abgeleiteten symmetrischen Schlüssel zu verschlüsseln. Dies ist so sicher wie der gewählte Passsatz. Ich würde vorschlagen, bei diesem Ansatz zu bleiben; Seine Konventionalität macht es "einfacher" als eine Lösung, die nicht gut untersucht wurde.

    14 January 2012
    erickson
  • Falls Sie ein asymmetrisches Schlüsselpaar aus einem Kennwort generieren möchten, finden Sie hier ein Beispielschema , das auch einige Diskussionen zu seiner Verwendung enthält (vollständige Offenlegung: Ich bin an der Definition des zugehörigen Standards beteiligt). Die Verwendung solcher "dezentraler Identitäten" bietet viele Möglichkeiten.

    Der Hauptnachteil besteht darin, dass sich die Benutzer nicht an "250-stellige Hex-Passwörter", die typischen Benutzer, erinnern müssen. halb zufälliges 8-stelliges Passwort "schneidet es nicht ab. Das Passwort muss ausreichend lang und ausreichend zufällig sein, so dass der zugehörige Schlüsselraum von aus Passwortdaten erzeugten asymmetrischen Schlüsseln groß genug ist, um Brute-Force-Angriffen zu widerstehen, z. im Bereich von ~ 16 völlig zufälligen Zeichen in der Gruppe az, AZ, 0-9.

    Der Vorteil eines Benutzers, ein einzelnes "wirklich komplexes" Passwort zu lernen, ist jedoch dasselbe Schlüsselpaar kann mit mehreren Diensten verwendet werden, und verschiedene Schlüssel (Identitäten) können leicht erzeugt werden, indem geringfügige nicht zufällige Variationen in die Eingabedaten der Schlüsselerzeugung eingefügt werden.

    Hier ist ein Python Beispiel der Schlüsselgenerierung anhand des Kennworts (die zugehörige Bibliothek ist also Open Source Ich kann es einfach ausprobieren und auch den Code zur Schlüsselgenerierung in der Quelle nachschlagen).

    16 January 2012
    Adam Wright