Sunday, 15 September 2019

Java: AES Symmetric encryption example


Symmetric Encryption
In Symmetric encryption a secret key (K) is used to both encryption and decryption.

As you see above image, plain message and secret key are fed to an encryption algorithm like AES to encrypt the message.


Similarly same key is used to decrypt the encrypted message.

Symmetric key encryption algorithm examples
a.   AES (Advanced Encryption Standard)
b.   DES (Data Encryption Standard)
c.    IDEA (International Data Encryption Algorithm)
d.   Blowfish
e.   RC4 (Rivest Cipher 4)
f.     RC5 (Rivest Cipher 5)
g.   RC6 (Rivest Cipher 6)

Encrypt the message using AES algorithm
Step 1: Define secret key and initial data that is fed to the AES algorithm.

CryptoUtil(String secretKey, String initialData) {
 SECRET_KEY = secretKey;
 INITIAL_DATA = initialData;
 
 try {
  KEY_BYTES = SECRET_KEY.getBytes(CHARSET);
  INITIAL_VALUE_BYTES = INITIAL_DATA.getBytes(CHARSET);
 
 } catch (UnsupportedEncodingException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }
 AES_KEY = new SecretKeySpec(KEY_BYTES, KEY_SPEC);
}
 
Step 2: Get the instance of cipher using AES algorithm.
Cipher cipher = Cipher.getInstance(ALGORITHM)

Step 3: Initialize the cipher with encrypt mode and set the initial data.
cipher.init(Cipher.ENCRYPT_MODE, AES_KEY, new IvParameterSpec(INITIAL_VALUE_BYTES));

Step 4: Encrypt the data using cipher.
byte[] msgBytes = message.getBytes(CHARSET);
byte[] encrypted = cipher.doFinal(msgBytes);
String encryptedData = new String(BASE_64_ENCODER.encode(encrypted), CHARSET)

Decrypt the encrypted message using AES algorithm

Step 1:  Define secret key and initial data that is fed to the AES algorithm.
CryptoUtil(String secretKey, String initialData) {
 SECRET_KEY = secretKey;
 INITIAL_DATA = initialData;
 
 try {
  KEY_BYTES = SECRET_KEY.getBytes(CHARSET);
  INITIAL_VALUE_BYTES = INITIAL_DATA.getBytes(CHARSET);
 
 } catch (UnsupportedEncodingException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }
 AES_KEY = new SecretKeySpec(KEY_BYTES, KEY_SPEC);
}
 
Step 2: Decode the encoded message.
byte[] decodedMsgBytes = BASE_64_DECODER.decode(message.getBytes(CHARSET));

Step 3: Initialize the cipher in decrypt mode.
cipher.init(Cipher.DECRYPT_MODE, AES_KEY, new IvParameterSpec(INITIAL_VALUE_BYTES));

Step 4: Get the decrypted message.
byte[] decrypted = cipher.doFinal(decodedMsgBytes);
String decryotedMsg = new String(decrypted, CHARSET);

Find the below working application.

CryptoUtil.java
package com.sample.app.util;
 
import java.io.UnsupportedEncodingException;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;
 
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
 
public class CryptoUtil {
 private static final String CHARSET = "UTF-8";
 private static final String ALGORITHM = "AES/CTR/NoPadding";
 private static final String KEY_SPEC = "AES";
 private static final Encoder BASE_64_ENCODER = Base64.getEncoder();
 private static final Decoder BASE_64_DECODER = Base64.getDecoder();
 
 private String SECRET_KEY;
 private String INITIAL_DATA;
 
 private byte[] KEY_BYTES;
 
 private byte[] INITIAL_VALUE_BYTES;
 
 private static SecretKey AES_KEY;
 
 private CryptoUtil(String secretKey, String initialData) {
  SECRET_KEY = secretKey;
  INITIAL_DATA = initialData;
 
  try {
   KEY_BYTES = SECRET_KEY.getBytes(CHARSET);
   INITIAL_VALUE_BYTES = INITIAL_DATA.getBytes(CHARSET);
 
  } catch (UnsupportedEncodingException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  AES_KEY = new SecretKeySpec(KEY_BYTES, KEY_SPEC);
 }
 
 public static CryptoUtil getInstance(String secretKey, String initialData) {
  return new CryptoUtil(secretKey, initialData);
 }
 
 public String encrypt(String message) {
  if (message == null || message.isEmpty()) {
   return message;
  }
  try {
 
   final Cipher cipher = Cipher.getInstance(ALGORITHM);
   cipher.init(Cipher.ENCRYPT_MODE, AES_KEY, new IvParameterSpec(INITIAL_VALUE_BYTES));
   byte[] msgBytes = message.getBytes(CHARSET);
   byte[] encrypted = cipher.doFinal(msgBytes);
 
   return new String(BASE_64_ENCODER.encode(encrypted), CHARSET);
  } catch (Exception e) {
   e.printStackTrace();
   throw new RuntimeException("Encryption failed encryptText");
  }
 }
 
 public String decrypt(String message) {
  if (message == null || message.isEmpty()) {
   return message;
  }
  try {
   final Cipher cipher = Cipher.getInstance(ALGORITHM);
   byte[] decodedMsgBytes = BASE_64_DECODER.decode(message.getBytes(CHARSET));
 
   cipher.init(Cipher.DECRYPT_MODE, AES_KEY, new IvParameterSpec(INITIAL_VALUE_BYTES));
 
   byte[] decrypted = cipher.doFinal(decodedMsgBytes);
   return new String(decrypted, CHARSET);
  } catch (Exception e) {
 
   throw new RuntimeException("Encryption failed encryptText");
  }
 }
}
 

App.java

package com.sample.app;
 
import com.sample.app.util.CryptoUtil;
 
public class App {
 
 public static void main(String args[]) {
 
  // AES only supports key sizes of 16, 24 or 32 bytes.
  String secret = "secret123secret1";
 
  //Initial Vector length must be 16 bytes long
  String initialData = "initialData12345";
 
  CryptoUtil cryptoUtil = CryptoUtil.getInstance(secret, initialData);
 
  String encryptedText = cryptoUtil.encrypt("Hello World");
  String decryptedText = cryptoUtil.decrypt(encryptedText);
 
  System.out.println("Encrypted Data : " + encryptedText);
  System.out.println("Decrypted Data : " + decryptedText);
 }
}
 
Output
Encrypted Data : ie6XmavEQbgCFEc=
Decrypted Data : Hello World

You may like



No comments:

Post a Comment