2012-07-16 14 views
10

Jestem prawie nowy w szyfrowaniu.Błąd odszyfrowywania: "nie podano iv, gdy oczekiwano"

Próbuję odszyfrować tablicę bajtów, a gdy dostarczam IV, otrzymuję wyjątek: InvalidAlgorithmParameterException (nie iv, jeśli oczekiwano).

Oto mój kod (iv jest tablica 16 bajtów, które nie jest NULL i ma wartości stosowanych przy szyfrowaniu):

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

Jeśli nie określić IV szyfr zostanie zainicjowane ok :

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

Próbując znaleźć odpowiedź znalazłem implementację JCEStreamCipher (here), które mogą nie odpowiadać wersji używam ale ma jakiś kod, który sprawia mi coś nie jestem ze zrozumieniem go correc tly.

Oto kod:

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"); 
     } 
    } 

Wygląda na to, że nie może dostarczyć IV podczas deszyfrowania, ale to nie czyni zbyt wiele dla mnie sens.

każda pomoc zostanie bardzo doceniona.

wielkie dzięki, richard.

+0

Przepraszam, ale tak naprawdę nie rozumiem twojego problemu. Być może powinieneś lepiej opublikować kod, którego używasz (więcej niż dwa wiersze) zamiast tego z JCEStreamCipher. – Robert

+0

Mówisz: "Wygląda na to, że nie mogę podać IV podczas odszyfrowywania" Dlaczego nie? Zwykła metoda polega na wstawianiu IV do przodu zaszyfrowanego tekstu i transmitowaniu ich razem. Odbiornik używa pierwszych 16 bajtów jako IV do odszyfrowania reszty wiadomości. – rossum

+0

Tak właśnie to robię, ale dostałem wyjątek, dostarczając IV do rozszyfrowania, co mnie zastanawiało. Podczas tworzenia klucza wystąpił błąd (właśnie wysłałem odpowiedź). – richardtz

Odpowiedz

13

Rozwiązany.

Użyłem niewłaściwego klawisza SecretKey, a nie tego, który można utworzyć dla AES.

Wcześniej miałem:

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

która tworzy JCEPBEKey.

mi brakuje:

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

który tworzy klucz jest właściwa dla AES.

+1

Doskonały. Ten błąd występował tylko w jednej starszej wersji urządzenia 4.0.3, która była w biurze, ale nie w innych. Teraz działa to na różnych platformach. –

Powiązane problemy