2012-11-06 10 views
8

Próbuję zaszyfrować/odszyfrować ciąg w Javie. Nie ma problemu z szyfrowaniem, a następnie przechowywane w tabeli sqlite. Ale zawsze ten sam błąd próbując go odszyfrować:Błąd odszyfrowywania w java

„java.security.InvalidKeyException: brak IV set, gdy jeden z oczekiwaniami”

Tu jest mój urywek kodu:

public String encrypt(String password){ 
    try 
    { 
     String key = "mysecretpassword"; 
     SecretKeySpec keySpec = null; 
     keySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES"); 
     Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); 
     cipher.init(Cipher.ENCRYPT_MODE, keySpec); 
     return new String(cipher.doFinal(password.getBytes())); 
    } 
    catch (Exception e) 
    { 
     return null; 
    } 
} 

public String decrypt(String password){ 
    try 
    { 
     String key = "mysecretpassword"; 
     SecretKeySpec keySpec = null; 
     keySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES"); 
     Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); 
     cipher.init(Cipher.DECRYPT_MODE,keySpec); 
     return new String(cipher.doFinal(password.getBytes())); 
    } 
    catch (Exception e) 
    { 
     System.out.println(e); 
     return null; 
    } 
} 

Czym jestem robić źle?

+0

Masz ten sam problem, nie rozumiem, dlaczego działa on przy szyfrowaniu i nie powiedzie się podczas odszyfrowywania? chyba że nie ustawiając IV w szyfrowaniu, generowany jest przypadek? – scottyab

+0

Tylko po to, aby kontynuować mój poprzedni komentarz. Tak, musisz ustawić IV podobny do pokazanego poniżej @Udo. – scottyab

+0

Możliwy duplikat [Błąd deszyfrowania: "nie ustawiono iv, gdy oczekiwano"] (http://stackoverflow.com/questions/11503157/decrypting-error-no-iv-set-when-one-expected) – rds

Odpowiedz

9

Musisz określić wektor inicjujący w cipher.init() metody:

IvParameterSpec ivSpec = new IvParameterSpec(ivBytes); 
cipher.init(Cipher.DECRYPT_MODE,keySpec, ivSpec); 

Patrz: http://docs.oracle.com/javase/1.5.0/docs/api/javax/crypto/spec/IvParameterSpec.html

Wektor inicjujący powinien być losową tablicą bajtów, dla dyskusji patrz:

http://en.wikipedia.org/wiki/Initialization_vector

+0

Dzięki! Dokumentacja i Twój fragment były bardzo pomocne! – MademoiselleLenore

+0

Co powinno oznaczać ivBytes? – sajattack

+0

Do odpowiedzi dodałem informacje o IV. –

1

Trzeba odpowiedniego klucza AES, spróbuj:

String key = "mysecretpassword"; 
KeySpec spec = new PBEKeySpec(key.toCharArray(), Salt, 12345678,256); 
SecretKey encriptionKey = factory.generateSecret(spec); 
Key encriptionKey = new SecretKeySpec(encriptionKey.getEncoded(), "AES"); 
+0

encryptionKey jest określony dwa razy. To nie wydaje się właściwe ... – PearsonArtPhoto