I’m trying to write a simple program to encrypt and decrypt files using the AES algortihm. The intention later is to use split the simple program into encryption and decrytion methods in a more complex program.
He is the encryption part of the program:
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(128);
SecretKey key = kg.generateKey();
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.ENCRYPT_MODE, key);
FileInputStream fis; FileOutputStream fos; CipherOutputStream cos;
fis = new FileInputStream("FileTo.encrypt");
fos = new FileOutputStream("Encrypted.file");
//write encrypted to file
cos = new CipherOutputStream(fos, c);
byte[] b = new byte[16];
int i = fis.read(b);
while (i != -1) {
cos.write(b, 0, i);
i = fis.read(b);
}
cos.close();
//write key to file
byte[] keyEncoded = key.getEncoded();
FileOutputStream kos = new FileOutputStream("crypt.key");
kos.write(keyEncoded);
kos.close();
Here’s the decryption part:
//Load Key
FileInputStream fis2= new FileInputStream("a.key");
File f=new File("a.key");
long l=f.length();
byte[] b1=new byte[(int)l];
fis2.read(b1, 0, (int)l);
SecretKeySpec ks2=new SecretKeySpec(b1,"AES");
Cipher c1 = Cipher.getInstance("AES");
c1.init(Cipher.DECRYPT_MODE, ks2);
FileInputStream fis1=new FileInputStream("Encrypted.file");
CipherInputStream in= new CipherInputStream(fis1,c1);
FileOutputStream fos0 =new FileOutputStream("decrypted.file");
byte[] b3=new byte[1];
int ia=in.read(b3);
while (ia >=0)
{
c1.update(b3); //<-------remove this
fos0.write(b3, 0, ia);
ia=in.read(b3);
}
in.close();
fos0.flush();
fos0.close();
Now the problem is the decryption part is not decrypting the last bits, some bits are missing. It seems to me that it only decrypts every 16 bytes, but the variable in(cipherinputstream) returns -1 when it should be returning the last bytes.
How do I get the last bits?
Thanks in advance
Edited: Added comment to point out what has to be removed. Here’s some code to properly (i.e., without loading the entire file in java) encrypt and decrypt a file in Java using AES. It’s possible to add additional parameters (padding, etc.) but here’s the basic code.
You just need to remove this line in your code and it’ll work fine:
Since you’re using a
CipherInputStreamyou don’t need to update theCiphermanually. It handles that for you, and by calling it you’re interfering with the decryption.On a side note, for efficiency you should increase the size of your
byte[] bandbyte[] b3arrays. Typically 8192 is a good size for buffering.