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
Post a Comment