it-swarm.com.de

Einfache Methode zum Speichern/Wiederherstellen des Verschlüsselungsschlüssels zum Entschlüsseln von Zeichenfolgen in Java

Zur Verschlüsselung verwende ich so etwas:

SecretKey aesKey = KeyGenerator.getInstance("AES").generateKey();
StringEncrypter aesEncrypt = new StringEncrypter(aesKey, aesKey.getAlgorithm());
String aesEncrypted= aesEncrypt.encrypt(StringContent);

Wenn ich aesKey ausdrucken möchte, bekomme ich: "[email protected]".

Für die Verschlüsselung möchte ich den Benutzer nach dem Schlüssel fragen, aber ich weiß nicht, wie und in welchem ​​Format es sein soll. Mein Plan sah so aus:

SecretKey aesKey = [email protected];
StringEncrypter aesEncrypt = new StringEncrypter(aesKey, aesKey.getAlgorithm());
String aesDecrypt = aesEncrypt.decrypt(aesEncrypted);

Aber es scheint nicht zu funktionieren. Gibt es eine einfache Möglichkeit, den Schlüssel nach der Verschlüsselung auf der Konsole auszudrucken, damit der Benutzer ihn speichern kann (oder sich daran erinnern kann) und dann für die Entschlüsselung verwenden kann?

Der gesamte Code ist hier: Cyphertext kann nicht aus Textdatei entschlüsselt werden, symmetrischer Schlüssel implementiert. in Java Also ich entschuldige mich für das erneute Posten, aber ich bin mir nicht sicher, ob der Code überhaupt lesbar ist (ich bin Neuling).

15
dave91

Ich musste das kürzlich selbst machen. Und während die anderen Antworten mich hier in die richtige Richtung führten, hätte es einfacher sein können. Hier also mein "Anteil" für den Tag, ein paar Hilfsmethoden für die einfache AES-Schlüsselmanipulation. (Beachten Sie die Abhängigkeit von Apache Commons und Codec.)

Dies ist alles in einem Git-Repo: github.com/stuinzuri/SimpleJavaKeyStore

import static org.Apache.commons.codec.binary.Hex.*;
import static org.Apache.commons.io.FileUtils.*;
import Java.io.*;
import Java.security.NoSuchAlgorithmException;
import javax.crypto.*;
import org.Apache.commons.codec.DecoderException;

public static SecretKey generateKey() throws NoSuchAlgorithmException
{
    KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
    keyGenerator.init(256); // 128 default; 192 and 256 also possible
    return keyGenerator.generateKey();
}

public static void saveKey(SecretKey key, File file) throws IOException
{
    char[] hex = encodeHex(key.getEncoded());
    writeStringToFile(file, String.valueOf(hex));
}

public static SecretKey loadKey(File file) throws IOException
{
    String data = new String(readFileToByteArray(file));
    byte[] encoded;
    try {
        encoded = decodeHex(data.toCharArray());
    } catch (DecoderException e) {
        e.printStackTrace();
        return null;
    }
    return new SecretKeySpec(encoded, "AES");
}
21
Stu Thompson

Die meisten Java Key-Instanzen werden als Folge von Bytes dargestellt, die sich aus ihrer getEncoded() -Methode ergeben. Dies muss gespeichert werden, um den Schlüssel später wieder herzustellen.

Um einen Schlüssel jedoch in elektronischer Form sicher zu speichern, sollte er verschlüsselt werden. Natürlich erfordert das Verschlüsseln des Schlüssels einen anderen Schlüssel (oder ein anderes Kennwort) ... und Sie haben also einen unendlichen Regress. Eine Java-Variable KeyStore kann verwendet werden, um SecretKey-Objekte auf diese Weise zu speichern. Dies ist nützlich, wenn Sie über viele Geheimschlüssel verfügen, die alle durch ein einziges "Master" -Kennwort geschützt sind. Aber für den Schutz eines einzelnen Schlüssels ist es nicht sehr sinnvoll.

Eine Alternative besteht darin, den Schlüssel dem Benutzer in einer Form zu präsentieren, die auf eine sichere Art und Weise gespeichert werden kann (in vielen Anwendungen liegt dies möglicherweise auf einem Zettel in der Brieftasche). Dies kann so einfach sein wie das Anzeigen der Bytes des Schlüssels, der in Hexadezimal-, Base-64- oder anderer Textcodierung codiert ist, und das Auffordern des Benutzers, ihn aufzuschreiben.

Ein anderer Ansatz besteht darin, dem Benutzer zu erlauben, ein einprägsames Passwort zu wählen und damit einen Schlüssel zu generieren, wobei ein Algorithmus wie PBKDF2 verwendet wird. Das Salt (und möglicherweise die Iterationszahl), das für die Schlüsselableitung verwendet wird, müsste jedoch irgendwo aufgezeichnet werden. Ein weiterer Nachteil besteht darin, dass die Nutzer dazu neigen, aus einer relativ begrenzten Anzahl von Passwörtern aus der Gesamtzahl der verfügbaren Passwörter zu wählen. Schlüssel, die von Kennwörtern abgeleitet werden, sind daher möglicherweise einfacher zu erraten, als die Schlüsselgröße vermuten lässt.


Hier ist eine Illustration der grundlegenden Technik zum Bestehen und Wiederherstellen eines geheimen Schlüssels.

byte[] encoded = aesKey.getEncoded();
/* Now store "encoded" somewhere. For example, display the key and 
   ask the user to write it down. */
String output = Base64.getEncoder().withoutPadding().encodeToString(encoded);
System.out.println("Keep it secret, keep it safe! " + output);

...

/* At some point, you need to reconstitute the key. Let's say the user 
   enters it as a base-64 number that you convert to bytes. */
String input = ... ;
byte[] encoded = Base64.getDecoder().decode(input);
SecretKey aesKey = new SecretKeySpec(encoded, "AES");
13
erickson

Ich habe Schlüssel in Java-Keystore-Dateien gespeichert. Hier ist ein Artikel, der Ihnen helfen kann

http://www.informit.com/articles/article.aspx?p=170967&seqNum=3

4
BillMan

Nur zur Information: Die Ausgabe, die Sie sehen, ist das Ergebnis der Standardmethode toString und die lustige Zahl am Ende ist ein Hash-Code. Siehe hier . Hash-Codes sind vom Entwurf her nicht reversibel, und toString gibt nicht notwendigerweise genügend Informationen zum Rekonstruieren des ursprünglichen Objekts (obwohl dies für bestimmte Klassen gilt).

0
Dan