Java AES / GCM / NoPadding - Was gibt mir cipher.getIV ()?
Ich bin mit AES/GCM/NoPadding
Verschlüsselung in Java 8 und ich Frage mich, ob mein code hat eine Sicherheitslücke. Mein code scheint Arbeitdass es verschlüsselt und entschlüsselt text, aber ein paar details sind noch unklar.
Meine wichtigste Frage ist diese:
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] iv = cipher.getIV(); //?????
Tut, IV erfüllen die Anforderungen der "Für einen bestimmten Schlüssel, der IV DARF sich NICHT wiederholen." aus RFC 4106?
Ich würde auch schätzen, alle Antworten /Erkenntnisse für meine Fragen (siehe unten), aber, die erste Frage, die nervt mich am meisten. Ich weiß nicht, wo zu finden, Quellcode oder Dokumentation, die Antworten.
Hier ist der vollständige code, etwa. Ich entschuldige mich, falls ich die eingeführte Fehler beim schreiben von diesem post:
class Encryptor {
Key key;
Encryptor(byte[] key) {
if (key.length != 32) throw new IllegalArgumentException();
this.key = new SecretKeySpec(key, "AES");
}
//the output is sent to users
byte[] encrypt(byte[] src) throws Exception {
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] iv = cipher.getIV(); //See question #1
assert iv.length == 12; //See question #2
byte[] cipherText = cipher.doFinal(src);
assert cipherText.length == src.length + 16; //See question #3
byte[] message = new byte[12 + src.length + 16]; //See question #4
System.arraycopy(iv, 0, message, 0, 12);
System.arraycopy(cipherText, 0, message, 12, cipherText.length);
return message;
}
//the input comes from users
byte[] decrypt(byte[] message) throws Exception {
if (message.length < 12 + 16) throw new IllegalArgumentException();
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec params = new GCMParameterSpec(128, message, 0, 12);
cipher.init(Cipher.DECRYPT_MODE, key, params);
return cipher.doFinal(message, 12, message.length - 12);
}
}
Angenommen, dass die Nutzer cracking my secret key = Spiel über.
Detailliertere Fragen /Fragen:
- Ist die IV zurückgegeben Chiffre.getIV() sicher für mich zu gebrauchen?
- Tut es vermeiden die Katastrophe, die der Wiederverwendung der IV,Tastenkombination im Galois/Counter-Mode?
- Ist es noch sicherer, wenn ich mehrere Anwendungen ausführen dieses Codes auf einmal, alle anzeigen, verschlüsselte Nachrichten an Benutzer aus der gleichen src-Daten (möglicherweise in der gleichen Millisekunde)?
- Was ist der zurückgegebene IV aus? Ist es eine Atomare Zähler plus einige zufällige Rauschen?
- Muss ich vermeiden
cipher.getIV()
und konstruieren eine IV-mich selbst, mit meinen eigenen counter? - Ist der Quell-code der Implementierung
cipher.getIV()
online verfügbar irgendwo, vorausgesetzt, ich bin mit Oracle JDK 8 + JCE Unlimited Strength-Erweiterung?
- Ist, dass IV immer 12 bytes lang?
- Ist die Authentifizierung tag immer 16 bytes (128 bits) lang ist?
- Mit #2 und #3, und der Mangel an Polsterung, bedeutet das, dass meine verschlüsselte Nachrichten sind immer
12 + src.length + 16
bytes lang? (Und so kann ich sicher, dass du Sie in ein byte-array, die ich weiß, die richtige Länge?) - Ist es sicher für mich zu Anzeige eine unbegrenzte Anzahl von src-Daten-Verschlüsselung, um die Benutzer, VORGEGEBENE Konstante src-Daten, die der Nutzer wissen?
- Ist es sicher für mich zu Anzeige eine unbegrenzte Anzahl von src-Daten-Verschlüsselung, um die Benutzer, wenn Sie die src-Daten ist jedes mal anders (z.B. mit der
System.currentTimeMillis()
oder Zufallszahlen)? - Würde es helfen, wenn ich tappste Sie die src-Daten mit Zufallszahlen vor der Verschlüsselung? Also 8 zufällige bytes in front und Rücken, oder nur an einem Ende? Oder würde das nicht helfen /machen meiner Verschlüsselung schlimmer?
(Denn diese Fragen sind alle über den gleichen block von meinem eigenen code, und Sie sind stark miteinander verwandt, und andere könnten/sollten, haben die gleichen Fragen bei der Umsetzung der gleichen Funktionalität, es fühlte sich falsch aufteilen der Fragen in mehrere Beiträge. Kann ich re-poste Sie separat, wenn das ist besser geeignet für StackOverflow-format. Lassen Sie mich wissen!)
InformationsquelleAutor der Frage Michael Hixson | 2015-08-06
Du musst angemeldet sein, um einen Kommentar abzugeben.
Q1: Ist die IV zurückgegeben Chiffre.getIV() sicher für mich zu gebrauchen?
Ja, es ist zumindest für die von Oracle bereitgestellte Implementierung. Es wird separat generiert mit Hilfe des Standard -
SecureRandom
Umsetzung. Wie es ist 12 Byte groß sind (der Standardwert für GCM) dann haben Sie 96 bits von Zufälligkeit. Die chance, dass der Zähler wiederholt, ist verschwindend klein. Sie können sich die Quelle in der OpenJDK (GPL), die das Oracle JDK basiert.Ich würde allerdings noch empfehlen, die Sie für die Erstellung Ihrer eigenen 12 zufällige bytes als andere Anbieter könnten sich anders Verhalten.
Q2: Ist, dass IV immer 12 bytes lang?
Es ist sehr wahrscheinlich, wie es das GCM-Standard, aber auch in anderen Längen sind gültig für GCM. Der Algorithmus wird jedoch eine zusätzliche Berechnungen für jede andere Größe ist als 12 Byte. Aufgrund der Schwächen ist es dringend empfohlen, zu halten, bei 12 Byte /96 bits und API - einschränken können Sie, die Wahl von IV Größe.
Q3: Ist die Authentifizierung tag immer 16 bytes (128 bits) lang ist?
Nein, es kann jede beliebige Größe in bytes reichen von 64 bit auf 128 bit mit 8 bit-Schritten. Wenn es kleiner ist, es besteht lediglich aus der äußersten linken bytes der Authentifizierung, tag obwohl. Sie können geben Sie eine andere Größe-tag mit
GCMParameterSpec
als Dritten parameter für Ihreinit
nennen.Beachten Sie, dass die Stärke der GCM ist stark abhängig von der Größe des Tags. Ich würde empfehlen, es auf 128 bit. 96 bits sollte die minimale besonders wenn Sie möchten, erzeugen eine Menge von Chiffretext.
Q4: Mit #2 und #3, und der Mangel an Polsterung, bedeutet das, dass meine verschlüsselte Nachrichten sind immer 12 + src.Länge + 16 bytes lang? (Und so kann ich sicher, dass du Sie in ein byte-array, die ich weiß, die richtige Länge?)
Siehe oben. Für die Oracle-provider ist dies der Fall. Verwenden
GCMParameterSpec
sicher zu sein.Q5: Ist es sicher für mich zu Anzeige eine unbegrenzte Anzahl von src-Daten-Verschlüsselung, um die Benutzer, VORGEGEBENE Konstante src-Daten, die der Nutzer wissen?
Praktisch ungebunden, ja. Ich würde anfangen, sich Gedanken nach etwa 2^48-Verschlüsselung. Im Allgemeinen sollten Sie jedoch design für key ändern.
Q6: Ist es sicher für mich zu Anzeige eine unbegrenzte Anzahl von src-Daten-Verschlüsselung, um die Benutzer, wenn Sie die src-Daten ist jedes mal anders (z.B. mit System.currentTimeMillis() oder Zufallszahlen)?
Siehe Antwort zu Frage 5
Q7: Würde es helfen, wenn ich tappste Sie die src-Daten mit Zufallszahlen vor der Verschlüsselung? Also 8 zufällige bytes in front und Rücken, oder nur an einem Ende? Oder würde das nicht helfen /machen meiner Verschlüsselung schlimmer?
Nein, es würde nicht helfen bei allen. GCM verwendet CTR-Modus darunter, so würde es nur werden, verschlüsselt mit dem Schlüssel-stream. Es würde nicht als IV. Wenn Sie eine nahezu grenzenlose Anzahl von ciphertexts (höher als 2^48!) dann würde ich vorschlagen, Sie verwenden, die Zufallszahl und den key für ein key-derivation-Funktion oder KDF. HKDF ist derzeit bester der Rasse, aber möglicherweise müssen Sie verwenden Hüpfburg oder es selbst implementieren.
InformationsquelleAutor der Antwort Maarten Bodewes