This Java tutorial is to learn about using AES password based encryption (PBE) to encrypt and decrypt a file. In the previous tutorial we saw about using TripleDES PBE to encrypt and decrypt a file. AES is more advanced and secure than TripleDES.
In this tutorial we will have simple text file with plain text. This can be any type of file. We will encrypt this into another file with an extension .des For encryption we will use a plain text password, then an iv which is used to initialize the cipher and a salt which is used for encoding.
All these three, password, iv and salt should be passed on to the recipient in a secure mechanism and not along with the encrypted file. The recipient will use the plain text password, iv (to initialize the cypher) and the salt to decrypt the file. In our example tutorial, we will again write back the decrypted content to a plain text file. So once the process is over the input text file and the output text file content should match.
Following Java code is to encrypt a file. To test this, put a file named “plainfile.txt” in project root.
package com.javapapers.java.security; import java.io.FileInputStream; import java.io.FileOutputStream; import java.security.AlgorithmParameters; import java.security.SecureRandom; import java.security.spec.KeySpec; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; public class AESFileEncryption { public static void main(String[] args) throws Exception { // file to be encrypted FileInputStream inFile = new FileInputStream("plainfile.txt"); // encrypted file FileOutputStream outFile = new FileOutputStream("encryptedfile.des"); // password to encrypt the file String password = "javapapers"; // password, iv and salt should be transferred to the other end // in a secure manner // salt is used for encoding // writing it to a file // salt should be transferred to the recipient securely // for decryption byte[] salt = new byte[8]; SecureRandom secureRandom = new SecureRandom(); secureRandom.nextBytes(salt); FileOutputStream saltOutFile = new FileOutputStream("salt.enc"); saltOutFile.write(salt); saltOutFile.close(); SecretKeyFactory factory = SecretKeyFactory .getInstance("PBKDF2WithHmacSHA1"); KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 65536, 256); SecretKey secretKey = factory.generateSecret(keySpec); SecretKey secret = new SecretKeySpec(secretKey.getEncoded(), "AES"); // Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secret); AlgorithmParameters params = cipher.getParameters(); // iv adds randomness to the text and just makes the mechanism more // secure // used while initializing the cipher // file to store the iv FileOutputStream ivOutFile = new FileOutputStream("iv.enc"); byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV(); ivOutFile.write(iv); ivOutFile.close(); //file encryption byte[] input = new byte[64]; int bytesRead; while ((bytesRead = inFile.read(input)) != -1) { byte[] output = cipher.update(input, 0, bytesRead); if (output != null) outFile.write(output); } byte[] output = cipher.doFinal(); if (output != null) outFile.write(output); inFile.close(); outFile.flush(); outFile.close(); System.out.println("File Encrypted."); } }
Following Java code is to decrypt the file. Run the above program prior to running this.
package com.javapapers.java.security; import java.io.FileInputStream; import java.io.FileOutputStream; import java.security.spec.KeySpec; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.PBEKeySpec; import javax.crypto.spec.SecretKeySpec; public class AESFileDecryption { public static void main(String[] args) throws Exception { String password = "javapapers"; // reading the salt // user should have secure mechanism to transfer the // salt, iv and password to the recipient FileInputStream saltFis = new FileInputStream("salt.enc"); byte[] salt = new byte[8]; saltFis.read(salt); saltFis.close(); // reading the iv FileInputStream ivFis = new FileInputStream("iv.enc"); byte[] iv = new byte[16]; ivFis.read(iv); ivFis.close(); SecretKeyFactory factory = SecretKeyFactory .getInstance("PBKDF2WithHmacSHA1"); KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, 65536, 256); SecretKey tmp = factory.generateSecret(keySpec); SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES"); // file decryption Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv)); FileInputStream fis = new FileInputStream("encryptedfile.des"); FileOutputStream fos = new FileOutputStream("plainfile_decrypted.txt"); byte[] in = new byte[64]; int read; while ((read = fis.read(in)) != -1) { byte[] output = cipher.update(in, 0, read); if (output != null) fos.write(output); } byte[] output = cipher.doFinal(); if (output != null) fos.write(output); fis.close(); fos.flush(); fos.close(); System.out.println("File Decrypted."); } }
Comments are closed for "Java File Encryption Decryption using AES Password Based Encryption (PBE)".
Good explanation…
Your IV and salt can be stored(embedded) in the file and it not be a security concern.
Getting below error while running this program.
Exception in thread “main” java.security.InvalidKeyException: Illegal key size or default parameters
at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1021)
at javax.crypto.Cipher.implInit(Cipher.java:796)
at javax.crypto.Cipher.chooseProvider(Cipher.java:859)
at javax.crypto.Cipher.init(Cipher.java:1229)
at javax.crypto.Cipher.init(Cipher.java:1166)
at com.javapapers.java.AESFileEncryption.main(AESFileEncryption.java:51)
I want to store encrypted bytes in ms sql db and later decrypt it with same key
Is there any implementation part of UMARAM algorithm
Its showing me the same errors that Nav is getting:
Exception in thread “main” java.security.InvalidKeyException: Illegal key size or default parameters
at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1011)
at javax.crypto.Cipher.implInit(Cipher.java:786)
at javax.crypto.Cipher.chooseProvider(Cipher.java:849)
at javax.crypto.Cipher.init(Cipher.java:1213)
at javax.crypto.Cipher.init(Cipher.java:1153)
at aesencrypt.main(aesencrypt.java:37)
sir
iam facing the same errors too
can you give explanation
If you get the java.security.InvalidKeyException you have to install the Java Cryptography Extension (JCE) unlimited strength jurisdiction policy files:
Java 6 link: http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html
Java 7 link: http://www.oracle.com/technetwork/java/embedded/embedded-se/downloads/jce-7-download-432124.html
Java 8 link: http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
If you use JDK copy unzipped jar files into folder: ${jdk.home}/jre/lib/security/
If you use JRE copy unzipped jar files into folder: ${jre.home}/lib/security/
Note that ${jdk.home} and ${jre.home} point to installation directory which depend on your OS.
Hope it helps.
Greetings,
Dragan Bjedov
By default java uses 128 Bit encryption. So change 256 to 126 in both codes. And it runs fine. :) I am not qa java expert. ;)
Yeah the same error occurred when i tried running the code too. But the key size 128 instead of 256 resolved it.
changing the 256 to 128 solves the problem in both cases. Thanks!
Thanks Man this is exactly what I have been searching for. Kudos n Big up
Getting the following exception during decryption. Please help.
Exception in thread “main” javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:811)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313)
at javax.crypto.Cipher.doFinal(Cipher.java:1970)
at encryption.AESFileDecryption.main(AESFileDecryption.java:53)
Thanks, very useful and interesting.
Thanks too, Dragan, for your advice on how to overcome the exception error
This is an AES encryption program, so why does it save the text to a .des file and not a .aes one?