encryption - Java Encrypt a file using aes256/ CBC/PKCS7Padding -
i'm trying encrypt file using aes256- cbc-pkcs7padding . i'm using bouncy castle library , exception
java.lang.illegalargumentexception: invalid parameter passed aes init - org.bouncycastle.crypto.params.parameterswithiv @ org.bouncycastle.crypto.engines.aesengine.init(unknown source) @ org.bouncycastle.crypto.paddings.paddedbufferedblockcipher.init(unknown source)
here source code :
public class crypto { public static final int aes_key_size = 256; public static int blocksize = 16; private final blockcipher aescipher = new aesengine(); private paddedbufferedblockcipher cipher = new paddedbufferedblockcipher(aescipher, new pkcs7padding()); private byte[] iv; private keyparameter key; public crypto() throws nosuchalgorithmexception { keygenerator kg = keygenerator.getinstance("aes"); kg.init(aes_key_size); secretkey sk = kg.generatekey(); key = new keyparameter(sk.getencoded()); } public void cryptozip(file plikzip, file plikaes) throws ioexception, datalengthexception, illegalstateexception, invalidciphertextexception { byte[] input = files.readallbytes(plikzip.topath()); byte[] cryptout = encrypt(input); fileoutputstream fos = new fileoutputstream(plikaes); fos.write(cryptout); fos.close(); } private byte[] encrypt(byte[] input) throws datalengthexception, illegalstateexception, invalidciphertextexception { iv = new byte[blocksize]; securerandom random = new securerandom(); random.nextbytes(iv); cipher.init(true, new parameterswithiv(key, iv)); // problem here byte[] output = new byte[cipher.getoutputsize(input.length)]; int byteswrittenout = cipher.processbytes( input, 0, input.length, output, 0); cipher.dofinal(output, byteswrittenout); return output; } }
any suggestion how fix , explanation i'm doing wrong helpful.
what you're missing indication of mode. if missing ecb mode assumed, , ecb mode doesn't take iv. paddedbufferedblockcipher
buffering, ecb mode. init mode passes parameters aesengine
, , aesengine
rejects iv accepts keys.
in code, following direct fix problem:
private final cbcblockcipher aesciphercbc = new cbcblockcipher(aescipher); private final paddedbufferedblockcipher cipher = new paddedbufferedblockcipher(aesciphercbc, new pkcs7padding());
i'll include following rewrite show different way of writing down. note didn't touch upon handling iv or exceptions correctly. obviously, large files, may want stream contents and/or map files.
// renamed crypto horrible name public class fileencryptor { // lets use uppercase constant names public static final int aes_key_size = 256; // field needed, rest can generated on fly private final keyparameter key; public fileencryptor() throws nosuchalgorithmexception { key = generatekey(); } private static keyparameter generatekey() { // removed keygenerator that's dependent on jca crypto-api securerandom keyrng = new securerandom(); byte[] keydata = new byte[aes_key_size / byte.size]; keyrng.nextbytes(keydata); return new keyparameter(keydata); } // code doesn't zip itself, no need include in method name public void encryptfile(file plaintextfile, file ciphertextfile) throws ioexception, datalengthexception, illegalstateexception, invalidciphertextexception { byte[] plaintext = files.readallbytes(plaintextfile.topath()); byte[] ciphertext = encrypt(plaintext); // try , symmetric, use files functionality reading *and writing* files.write(ciphertextfile.topath(), ciphertext); } private byte[] encrypt(byte[] plaintext) throws datalengthexception, illegalstateexception, invalidciphertextexception { // create cipher final blockcipher aes = new aesfastengine(); cbcblockcipher aescbc = new cbcblockcipher(aes); paddedbufferedblockcipher aescbcpadded = new paddedbufferedblockcipher(aescbc, new pkcs7padding()); // create iv byte[] iv = new byte[aes.getblocksize()]; securerandom random = new securerandom(); random.nextbytes(iv); // initialize cipher iv parameterswithiv paramswithiv = new parameterswithiv(key, iv); aescbcpadded.init(true, paramswithiv); // problem here // encrypt byte[] ciphertext = new byte[aescbcpadded.getoutputsize(plaintext.length)]; int byteswrittenout = aescbcpadded.processbytes( plaintext, 0, plaintext.length, ciphertext, 0); aescbcpadded.dofinal(ciphertext, byteswrittenout); // that's great, iv now? need include in returned ciphertext! return ciphertext; } }
Comments
Post a Comment