2012-05-31 20 views
11

Cuando se ejecuta debajo del programa, obtengo esta excepción. ¿No es capaz de descubrir qué problema con AES permite la clave de 128 -256 bits?Obtención de la excepción java.security.InvalidKeyException: Longitud de la clave AES inválida: ¿29 bytes?

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*..) 

Obtención de excepción en la línea 20

Aquí está el programa de

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

¿qué enunciado genera la excepción? – aioobe

+0

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

Respuesta

29

AES permite longitud de clave de 128, 192 o 256 bits. Eso es 16, 24 o 32 byte. Intente tomar solo los primeros 16 bytes de su mEncryptionKey como keyAsBytes.

Editar:
Una después de que se me ocurrió. Un hábito que he formado, y el que recomiendo, es tomar un hash SHA de una contraseña/frase de contraseña, y usar eso como los bytes de origen de su clave. Tomar un hash garantiza que los datos clave serán del tamaño correcto, independientemente de la duración de la contraseña/frase de contraseña. Su implementación actual del uso de los bytes String tiene dos problemas;

  • Romperá la generación de su clave si alguien usa una contraseña corta.
  • Dos contraseñas diferentes para las cuales los primeros 16 bytes son iguales crearán la misma clave.

Ambos problemas se eliminan mediante el uso de un hash.

Eche un vistazo al método buildKey() en esta clase; https://github.com/qwerky/DataVault/blob/master/src/qwerky/tools/datavault/DataVault.java

+0

Gracias Qwerky. Algunos más descubrimientos. Cuando le doy a myEncryptionKey 16 caracteres de longitud, es decir, 128 bits de longitud, este programa ejecuta multas pero cuando lo doy como 24 caracteres largos (192 bits de longitud) o 32 caracteres de longitud (256 bits de longitud), entonces aparece el error como " Tamaño de clave ilegal o parámetros predeterminados ". ¿Puedo establecer la longitud de la clave en 256 o 192 si quiero? –

+1

Para usar 192 o 256, es posible que deba habilitar los archivos de política de "fuerza de clave ilimitada". Esto se debe a una restricción legal en los Estados Unidos. Mira aquí; http://java.sun.com/developer/technicalArticles/Security/AES/AES_v1.html. Buscar 'Tamaño de clave ilegal o parámetros predeterminados' en este sitio, hay varias preguntas y respuestas al respecto. – Qwerky

+0

En su ejemplo en Datavault.java, se usa BouncyCastleProvider que no es una clase estándar de Java. Debido a algunas restricciones, debo ir solo con las clases estándar de Java. ¿Puedo utilizar alguna otra implementación de la clase de proveedor instalada de BouncyCastleProvider en el ejemplo que ha designado? –

1

La clave utiliza la aleatoriedad como entrada, pero hay requisitos adicionales para la forma en que se compone. El constructor SecretKeySpec que utilizó es para cargar una clave ya generada en la memoria. En su lugar, use KeyGenerator.

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

También tenga en cuenta que ahora se cree que AES-128 es más débil que AES-256. Probablemente no sea drásticamente diferente, pero el beneficio del tamaño de clave más largo puede ser compensado por las simplificaciones en otros lugares (menos rondas).

+1

Hola John. Quiero usar la tecla autoasignada, ya que la usaré como clave compartida. Quiero usar la clave que yo conozco y que no estoy asociada a la clave generada por el sistema. ¿Puedes arrojar algunas entradas sobre cómo puedo usar la clave asignada de cualquier longitud inferior a 256 bits en AES? –

Cuestiones relacionadas