2012-05-31 2 views
11

Wenn ich unter Programm laufe bekomme ich diese Ausnahme. Nicht in der Lage herauszufinden, was das Problem als AES den 128 -256-Bit-Schlüssel erlaubt?Ausnahmebedingung erhalten java.security.InvalidKeyException: Ungültige AES-Schlüssellänge: 29 Byte?

Exception in thread "main" java.security.InvalidKeyException: Invalid AES key length: 29 bytes 
at com.sun.crypto.provider.AESCipher.engineGetKeySize(DashoA13*..) 
at javax.crypto.Cipher.b(DashoA13*..) 

Erste Ausnahme in Zeile 20

Hier ist das Programm

import java.security.Key; 

import javax.crypto.Cipher; 
import javax.crypto.spec.SecretKeySpec; 

import sun.misc.BASE64Decoder; 
import sun.misc.BASE64Encoder; 

public class AESEncryptionDecryptionTest { 

    private static final String ALGORITHM  = "AES"; 
    private static final String myEncryptionKey = "ThisIsSecurityKey"; 
    private static final String UNICODE_FORMAT = "UTF8"; 

    public static String encrypt(String valueToEnc) throws Exception { 
Key key = generateKey(); 
Cipher c = Cipher.getInstance(ALGORITHM); 
c.init(Cipher.ENCRYPT_MODE, key); //////////LINE 20 
byte[] encValue = c.doFinal(valueToEnc.getBytes()); 
String encryptedValue = new BASE64Encoder().encode(encValue); 
return encryptedValue; 
    } 

public static String decrypt(String encryptedValue) throws Exception { 
Key key = generateKey(); 
Cipher c = Cipher.getInstance(ALGORITHM); 
c.init(Cipher.DECRYPT_MODE, key); 
byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedValue); 
byte[] decValue = c.doFinal(decordedValue); 
String decryptedValue = new String(decValue); 
return decryptedValue; 
} 

private static Key generateKey() throws Exception { 
byte[] keyAsBytes; 
keyAsBytes = myEncryptionKey.getBytes(UNICODE_FORMAT); 
Key key = new SecretKeySpec(keyAsBytes, ALGORITHM); 
return key; 
} 

public static void main(String[] args) throws Exception { 

String value = "password1"; 
String valueEnc = AESEncryptionDecryptionTest.encrypt(value); 
String valueDec = AESEncryptionDecryptionTest.decrypt(valueEnc); 

System.out.println("Plain Text : " + value); 
System.out.println("Encrypted : " + valueEnc); 
System.out.println("Decrypted : " + valueDec); 
} 

} 
+0

Welche Anweisung generiert die Ausnahme? – aioobe

+0

c.init (Cipher.ENCRYPT_MODE, Schlüssel); –

Antwort

29

AES 128, 192 oder 256 Bit Schlüssellänge ermöglicht. Das ist 16, 24 oder 32 Byte. Versuchen Sie, nur die ersten 16 Bytes Ihres mEncryptionKey als keyAsBytes zu nehmen.

Edit:
Ein nach obwohl mir einfiel. Eine Angewohnheit, die ich gebildet habe, und eine, die ich empfehle, ist, einen SHA-Hash eines Passworts/einer Passphrase zu nehmen und dieses als Quellbyte Ihres Schlüssels zu verwenden. Ein Hash-Wert garantiert, dass die Schlüsseldaten unabhängig von der Länge des Passworts/der Passphrase die richtige Größe haben. Ihre aktuelle Implementierung der Verwendung der String-Bytes hat zwei Probleme;

  • Es wird Ihre Schlüsselgenerierung unterbrechen, wenn jemand ein kurzes Passwort verwendet.
  • Zwei verschiedene Passwörter, bei denen die ersten 16 Bytes identisch sind, erzeugen den gleichen Schlüssel.

Diese beiden Probleme werden durch Verwendung eines Hashes beseitigt.

Werfen Sie einen Blick auf die buildKey() Methode in dieser Klasse; https://github.com/qwerky/DataVault/blob/master/src/qwerky/tools/datavault/DataVault.java

+0

Danke Qwerky. Einige weitere Befunde. Wenn ich myEncryptionKey als 16 Zeichen lang, dh 128 Bit Länge gebe, läuft dieses Programm fein, aber wenn ich es als 24 Zeichen lang (192 Bit Länge) oder 32 Zeichen lang (256 Bit Länge) gebe, bekomme ich den Fehler als " Ungültige Schlüsselgröße oder Standardparameter ". Kann ich die Schlüssellänge auf 256 oder 192 setzen, wenn ich möchte? –

+1

Um 192 oder 256 zu verwenden, müssen Sie möglicherweise die Richtliniendateien für "unbegrenzte Schlüsselstärke" aktivieren. Dies ist auf eine gesetzliche Beschränkung in den Vereinigten Staaten zurückzuführen. Siehe hier; http://java.sun.com/developer/technicalArticles/Security/AES/AES_v1.html. Suchen Sie nach 'Illegal key size 'oder' default parameters 'auf dieser Seite, es gibt einige Fragen und Antworten dazu. – Qwerky

+0

In Ihrem Beispiel in Datavault.java wird BouncyCastleProvider verwendet, was keine Standard-Java-Klasse ist. Aufgrund einiger Einschränkungen muss ich nur mit Standard-Java-Klassen gehen. Kann ich eine andere Implementierung der Provider-Klasse von BouncyCastleProvider in dem Beispiel verwenden, das Sie entwickelt haben? –

1

Der Schlüssel verwendet Zufälligkeit als Eingabe, aber es gibt weiterhin Anforderungen für die Zusammensetzung. Der verwendete SecretKeySpec-Konstruktor dient zum Laden eines bereits generierten Schlüssels in den Speicher. Verwenden Sie stattdessen KeyGenerator.

KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM); 
kg.init(128); 
SecretKey k = kg.generateKey(); 

Beachten Sie auch, dass AES-128 ist nun eigentlich gedacht, um schwächer als AES-256. Es ist wahrscheinlich nicht drastisch anders, aber der Vorteil von der längeren Schlüsselgröße kann durch Vereinfachungen an anderer Stelle (weniger Runden) aufgewogen werden.

+1

Hallo John. Ich möchte den selbst zugewiesenen Schlüssel verwenden, wie ich als Shared Key verwenden werde. Ich möchte den Schlüssel verwenden, der bekannt und von mir nicht systemgenerierter Schlüssel zugeordnet ist. Können Sie einige Eingaben werfen, wie kann ich den selbst zugewiesenen Schlüssel beliebiger Länge weniger als 256 Bit in AES verwenden? –

Verwandte Themen