2012-05-31 14 views
11

Quando si esegue sotto il programma sto ottenendo questa eccezione. Non riesci a capire quale sia il problema come AES che consente la chiave 128-256 bit?Ottenere l'eccezione java.security.InvalidKeyException: lunghezza della chiave AES non valida: 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*..) 

Come eccezione alla riga 20

Ecco il programma

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

quale istruzione genera l'eccezione? – aioobe

+0

c.init (Cipher.ENCRYPT_MODE, chiave); –

risposta

29

AES consente 128, 192 o 256 bit lunghezza della chiave. Quello è 16, 24 o 32 byte. Prova a prendere solo i primi 16 byte del tuo mEncryptionKey come keyAsBytes.

Modifica:
Un dopo mi è venuto in mente. Un'abitudine che ho formato e che raccomando è di prendere un hash SHA di una password/passphrase e usarlo come byte sorgente della tua chiave. L'acquisizione di un hash garantisce che i dati della chiave corrisponderanno alle dimensioni corrette, indipendentemente dalla lunghezza della password/passphrase. L'implementazione corrente dell'utilizzo dei byte String ha due problemi;

  • Si romperà la vostra generazione di chiavi se qualcuno usa una breve password.
  • Due password diverse per le quali i primi 16 byte sono uguali creeranno la stessa chiave.

Entrambi questi problemi vengono eliminati utilizzando un hash.

Dai un'occhiata al metodo buildKey() in questa classe; https://github.com/qwerky/DataVault/blob/master/src/qwerky/tools/datavault/DataVault.java

+0

Grazie Qwerky. Altre scoperte. Quando conferisco a myEncryptionKey una lunghezza di 16 caratteri, ovvero 128 bit, questo programma esegue delle multe, ma quando lo prendo come 24 caratteri (lunghezza 192 bit) o ​​32 caratteri (lunghezza 256 bit), ottengo l'errore come " Dimensione della chiave non valida o parametri predefiniti ". Posso impostare la lunghezza della chiave su 256 o 192 se voglio? –

+1

Per utilizzare 192 o 256, potrebbe essere necessario abilitare i file di criteri "forza chiave illimitata". Ciò è dovuto a una restrizione legale negli Stati Uniti. Vedere qui; http://java.sun.com/developer/technicalArticles/Security/AES/AES_v1.html. Cerca "Dimensione chiave illegale o parametri predefiniti" in questo sito, ci sono diverse domande e risposte a riguardo. – Qwerky

+0

Nel tuo esempio in Datavault.java, viene utilizzato BouncyCastleProvider che non è una classe java standard. A causa di alcune restrizioni ho bisogno di andare solo con le classi Java standard. Posso usare qualche altra implementazione della classe di provider instata di BouncyCastleProvider nell'esempio che hai escogitato? –

1

La chiave utilizza la casualità come input, ma ci sono requisiti di stiill per come è composta. Il costruttore SecretKeySpec utilizzato è per il caricamento di una chiave già generata in memoria. Utilizzare invece KeyGenerator.

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

Inoltre, si ritiene che AES-128 sia effettivamente più debole di AES-256. Probabilmente non è drasticamente diverso, ma il vantaggio derivante dalla maggiore dimensione della chiave potrebbe essere compensato da semplificazioni altrove (meno turni).

+1

Ciao John. Voglio usare la chiave assegnata automaticamente come userò come chiave condivisa. Voglio usare la chiave che è conosciuta e da me assegna non la chiave generata dal sistema. Puoi inserire alcuni input su come posso utilizzare la chiave assegnata automaticamente di qualsiasi lunghezza inferiore a 256 bit in AES? –

Problemi correlati