java - AES File decrypting “given final block not properly padded” -


i want encrypt , decrypt file use aes. have read many topics error "given final block not padded". don't find solution me.

sorry specify language of code, don't know write language java

here code :

variables

// iv, secret, salt in same time private byte[] salt = { 'h', 'u', 'n', 'g', 'd', 'h', '9', '4' }; public byte[] iv; public secretkey secret; 

createsecretkey

public void createsecretkey(string password){     secretkeyfactory factory = secretkeyfactory.getinstance("pbkdf2withhmacsha1");     keyspec spec = new pbekeyspec(password.tochararray(), salt, 65536, 256);     secretkey tmp = factory.generatesecret(spec);     secret = new secretkeyspec(tmp.getencoded(), "aes"); } 

method encrypt

public void encrypt(string inputfile){     fileinputstream fis = new fileinputstream(inputfile);     // save file: inputfile.enc     fileoutputstream fos = new fileoutputstream(inputfile + ".enc");      cipher cipher = cipher.getinstance("aes/cbc/pkcs5padding");     cipher.init(cipher.encrypt_mode, secret);      algorithmparameters params = cipher.getparameters();     // gen initialization vector     iv = (byte[]) ((ivparameterspec) params             .getparameterspec(ivparameterspec.class)).getiv();     // read file (plaint text)  -----> save .enc     int readbyte;     byte[] buffer = new byte[1024];     while ((readbyte = fis.read(buffer)) != -1) {         fos.write(cipher.dofinal(buffer), 0, readbyte);     }     fis.close();     fos.flush();     fos.close(); } 

method decrypt

public void decrypt(string inputfile){     fileinputstream fis = new fileinputstream(inputfile);     // save file: filename.dec     fileoutputstream fos = new fileoutputstream(inputfile.substring(0,             inputfile.length() - 4) + ".dec");      cipher cipher = cipher.getinstance("aes/cbc/pkcs5padding");     cipher.init(cipher.decrypt_mode, secret, new ivparameterspec(iv));     // read file encrypted  ---> .dec      int readbyte;     byte[] buffer = new byte[1024];     while ((readbyte = fis.read(buffer)) != -1) {         fos.write(cipher.dofinal(buffer), 0, readbyte);     }     fos.flush();     fos.close();     fis.close(); } 

update

solution: edit size of buffer multiples of 16. use cipherinput/ output read/ write file.

tks artjom b.

aes block cipher , such works on blocks of 16 bytes. mode of operation such cbc enables chain multiple blocks together. padding such pkcs#5 padding enables encrypt arbitrary length plaintext filling plaintext next multiple of block size.

the problem you're encrypting every 1024 bytes separately. since 1024 divides block size, padding adds full block before encryption. ciphertext chunks therefore 1040 bytes long. during decryption, you're reading 1024 missing padding. java tries decrypt , tries remove padding. if padding malformed (because it's not there), exception thrown.

easy fix

simply increase buffer decryption 1040 bytes.

proper fix

don't encrypt in separate chunks, either use cipher#update(byte[], int, int) instead of cipher.dofinal update ciphertext every buffer read or use cipherinputstream.


other security considerations:

you're missing random iv. without it, may possible attacker see encrypted same plaintext under same key observing ciphertexts.

you're missing ciphertext authentication. without it, can't reliably detect (malicious) changes in ciphertexts , may open system attacks such padding oracle attack. either use authenticated mode gcm or run created ciphertext through hmac create authentication tag , write end. can verify tag during/before decryption.


Comments