In this article the reader will learn about plain text file encryption using AES(Advanced Encryption Standard) algorithm.
In modern day cryptography AES algorithm gained much popularity because of its strength.
The message to be encrypted is called the plain text or clear text. The encrypted message, which is not in human readable format is called as cipher text.
Make data easy with Helical Insight.
Helical Insight is the world’s best open source business intelligence tool.
In cryptography systems there are two main types of encryption standards.
- Public Key Cryptography
- Private Key Cryptography
In public key cryptography, there will be two keys for each party. One is private key and the other one is public key. The public key of the recipient is used by the sender for enctyption and the private key is used by the recipient for decryption. This kind of cryptography is also called as Assymetric key cryptography.
In Private key cryptography, there will be only one shared key between the two parties for both encryption and decryption. In this mode of cryptography maintaining the secrecy of the secret key is very important. This kind of cryptography is also called as Symmetric key cryptography.
In general the Asymmetric key cryptography is used for short messages such as encrypting passwords. Symmetric key cryptography is used for encrypting relatively long messages. In cryptography systems like PGP(Pretty Good Privacy) both kinds of cryptography techniques are used.
AES(Advanced Encryption Standard)
The key size of AES is in general 128 bits. Where as 256 bits and 512 bits keys are also possible to use. The javax.crypto package of the Java language has the implementation of the AES algorithm. For 256 bit key encryption/decryption special policy files should be copied into the \jre\lib\security
directory, which can be downloaded from Oracle’s web site.
AES uses a block size of 16 bytes. That means it will encrypt the data in block sizes of 16 bytes. So, the plain text should be in multiples of size 16 bytes. But, a file may consist of data of any length. So, in order to encrypt data of length which is not multiples of 16 bytes we can use the following class CipherInputStream
. This class can be used to encrypt a stream of plaintext.
public class Encryptor { //The password, salt and initializationVector should be preserved for decryption private char[] password; private byte[] salt; private byte[] initializationVector; public Encryptor() { this.password = "Some string as password".toCharArray(); try { this.salt = "Some string as salt".getBytes("UTF-8"); //Note: initializationVector should be of length 16 bytes this.initializationVector = "Some string of length 16 bytes".getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } public static void main(String[] args) { Encryptor aes = new Encryptor(); //Pass the plaintext file and location of the encrypted file as command line arguments aes.encrypt(new File(args[0]), new File(args[1])); } public void encrypt(File plainTextFile, File encryptedLicenceFile) { if (encryptedLicenceFile.exists() == false) { try { encryptedLicenceFile.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } // To read the file to be encrypted FileInputStream fileInputStream = null; // To write the encrypted file FileOutputStream fileOutputStream = null; // To read the file information and to encrypt CipherInputStream cipherInputStream = null; try { fileInputStream = new FileInputStream(plainTextFile); fileOutputStream = new FileOutputStream(encryptedLicenceFile); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); KeySpec keySpec = new PBEKeySpec(password, salt, 65536, 128); SecretKey secretKey = keyFactory.generateSecret(keySpec); SecretKey secret = new SecretKeySpec(secretKey.getEncoded(), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); IvParameterSpec ivParameterSpec = new IvParameterSpec(initializationVector); cipher.init(Cipher.ENCRYPT_MODE, secret, ivParameterSpec); cipherInputStream = new CipherInputStream(fileInputStream, cipher); int read; while ((read = cipherInputStream.read()) != -1) { fileOutputStream.write((char) read); } fileOutputStream.flush(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidKeySpecException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (InvalidAlgorithmParameterException e) { e.printStackTrace(); } finally { try { if (fileInputStream != null) { fileInputStream.close(); } if (cipherInputStream != null) { cipherInputStream.close(); } if (fileOutputStream != null) { fileOutputStream.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
This code uses one plainTextFile and produces the encryptedFile. For decrypting we need to follow similar steps. The following code demonstrates the decryption. In the decrypt method we can use the following lines of code.
Make data easy with Helical Insight.
Helical Insight is the world’s best open source business intelligence tool.
// To read the ecrypted file FileInputStream fileInputStream = null; // To write decrypted file FileOutputStream fileOutputStream = null; // To read encrypted file and decrypt it CipherOutputStream cipherOutputStream = null; ByteArrayOutputStream byteArrayOutputStream = null; try { fileInputStream = new FileInputStream(ecncrypedFile); byteArrayOutputStream = new ByteArrayOutputStream(); SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); KeySpec keySpec = new PBEKeySpec(password, salt, 65536, 128); SecretKey secretKey = factory.generateSecret(keySpec); SecretKey secret = new SecretKeySpec(secretKey.getEncoded(), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); IvParameterSpec ivParameterSpec = new IvParameterSpec(initializationVector); cipher.init(Cipher.DECRYPT_MODE, secret, ivParameterSpec); cipherOutputStream = new CipherOutputStream(byteArrayOutputStream, cipher); byte[] buffer = new byte[4096]; int read; while ((read = fileInputStream.read(buffer)) != -1) { cipherOutputStream.write(buffer, 0, read); } if (cipherOutputStream != null) { //Unless you close here you won't get complete plain text cipherOutputStream.close(); } //The byte[] now can be used to obtain the cleartext byte[] plainText = byteArrayOutputStream.toByteArray();
The password, salt, and initializationVector must be the same while decrypting the cipher text. The decrypt method is left as reader’s exercise.
Thank you for reading.
Thanks and Regards,
Rajasekhar
Helical IT Solutions
Best Open Source Business Intelligence Software Helical Insight is Here