2012-07-16 13 views
10

Soy casi nuevo en el cifrado.Error de descifrado: "no iv set when one expected"

Estoy tratando de descifrar una matriz de bytes, y cuando estoy proporcionando el IV recibo una excepción: InvalidAlgorithmParameterException (no se establece iv cuando uno esperaba).

Aquí está mi código (iv es una matriz de 16 bytes que no es nula y tiene los valores utilizados en el cifrado):

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
cipher.init(Cipher.DECRYPT_MODE, encriptionKey,new IvParameterSpec(iv)); 

Si no especifico el IV el sistema de cifrado se inicializa bien :

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
cipher.init(Cipher.DECRYPT_MODE, encriptionKey); 

Tratando de encontrar una respuesta encontré una implementación de JCEStreamCipher (here) que pueden no corresponder a la versión que estoy usando, pero tiene un código que me hace algo que no soy la comprensión de que el correc Tly.

Aquí está el código:

if ((ivLength != 0) && !(param instanceof ParametersWithIV)) 
    { 
     SecureRandom ivRandom = random; 

     if (ivRandom == null) 
     { 
      ivRandom = new SecureRandom(); 
     } 

     if ((opmode == Cipher.ENCRYPT_MODE) || (opmode == Cipher.WRAP_MODE)) 
     { 
      byte[] iv = new byte[ivLength]; 

      ivRandom.nextBytes(iv); 
      param = new ParametersWithIV(param, iv); 
      ivParam = (ParametersWithIV)param; 
     } 
     else 
     { 
      throw new InvalidAlgorithmParameterException("no IV set when one expected"); 
     } 
    } 

Parece que no puedo proporcionar una vía intravenosa cuando el descifrado, pero no tiene demasiado sentido para mí.

cualquier ayuda será muy apreciada.

muchas gracias, richard.

+0

Lo siento, pero realmente no entiendo su problema. Puede ser que debería publicar el código que está utilizando (más de dos líneas) en lugar del de JCEStreamCipher. – Robert

+0

Usted dice: "Parece que no puedo proporcionar un IV al descifrar" ¿Por qué no? El método habitual es anteponer el IV al frente del texto cifrado y transmitirlos juntos. El receptor utiliza los primeros 16 bytes como IV para descifrar el resto del mensaje. – rossum

+0

Así es como lo estoy haciendo, pero obtuve la excepción cuando proporcioné el IV al desencriptador, lo cual me desconcertaba. Tuve un error al crear la clave (acaba de publicar la respuesta). – richardtz

Respuesta

13

Resuelto.

Estaba usando un SecretKey incorrecto, no el que puede crear para AES.

Anteriormente tuve:

KeySpec spec = new PBEKeySpec(password.toCharArray(), encryptionKeySalt, 12345,256); 
SecretKey encriptionKey = factory.generateSecret(spec); 

que crea un JCEPBEKey.

me faltaba:

Key encriptionKey = new SecretKeySpec(encriptionKey.getEncoded(), "AES"); 

que crea una clave apropiada para AES.

+1

Excelente. Este error solo ocurría en una versión anterior del dispositivo 4.0.3 que estaba en la oficina, pero no en las otras. Ahora esto funciona en todas las plataformas. –

Cuestiones relacionadas