Java Cryptography —Simplified (Part 1)
In this article, I'm going to show you how to encrypt your backend application's sensitive information, such as passwords in your DB, logging, or other downstream systems in a simplified manner. With the cloud, security becomes a quintessential requirement for sensitive information of our customers and having a basic understanding of how to secure your information becomes a necessity. There are multiple options available, but in this article, I'm going to show you a simple approach, and you could go for a more advanced approach based on your requirement and expertise.
In part one, I would like to show you how to use Symmetric Key Encryption and Decryption.
Before we get started, lets quickly go through some of the terminologies related to Java cryptography that will help you understand the code logic down the line.
Cryptography
Cryptography provides for secure communication in the presence of malicious third-parties — known as adversaries. Encryption (a major component of cryptography) uses an algorithm and a key to transform an input (i.e., Plain Text) into an encrypted output (i.e., ciphertext). A given algorithm will always transform the same Plain Text into the same ciphertext if the same key is used. Algorithms are considered secure if an attacker cannot determine any properties of the plaintext or key, given the ciphertext. An attacker should not be able to determine anything about a key is given a large number of Plain Text/ciphertext combinations, which used the key.
Symmetric and Asymmetric Cryptography
With symmetric cryptography, the same key is used for both encryption and decryption. A sender and a recipient must already have a shared key that is known to both. Key distribution is a tricky problem and was the impetus for developing asymmetric cryptography. With asymmetric crypto, two different keys are used for encryption and decryption. Every user in an asymmetric cryptosystem has both a public key and a private key. The private key is kept secret at all times, but the public key may be freely distributed.
Java Cryptography Architecture (JCA)
JCA is a framework for working with cryptography using the Java programming language. It forms part of the Java security API and was first introduced in JDK 1.1 in the java.security package. The JCA uses a "provider"-based architecture and contains a set of APIs for various purposes, such as encryption, key generation and management, secure random-number generation, certificate validation, etc. These APIs provide an easy way for developers to integrate security into application code
Java Cryptography Extension (JCE)
While JCA is tightly integrated with the core Java API and delivers the most basic cryptographic features, the latter one, JCE, provides various advanced cryptographic operations. In the past, both JCA and JCE libraries used to be treated differently by US export policies. Over time, however, the regulations were relaxed, and at present, they both are delivered as part of Java SE and the division is no longer important
AES (Acronym of Advanced Encryption Standard)
AES is a symmetric encryption algorithm. The algorithm was developed by two Belgian cryptographers, Joan Daemen and Vincent Rijmen. AES was designed to be efficient in both hardware and software and supports a block length of 128 bits and key lengths of 128, 192, and 256 bits.
AES data encryption is a more mathematically efficient and elegant cryptographic algorithm, but its main strength rests in the option for various key lengths. AES allows you to choose a 128-bit, 192-bit, or 256-bit key, making it exponentially stronger than the 56-bit key of DES.
public String generateKey(){
SecretKey secretKey;
KeyGenerator keygen = null;
try {
keygen = KeyGenerator.getInstance("AES");
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
keygen.init(256) ;
secretKey = keygen.generateKey();
String keyString = Base64.getEncoder().encodeToString(secretKey.getEncoded());
System.out.println("Generated Key: "+ keyString);
return keyString;
}
public String encrypt(String strToEncrypt) throws Exception {
if(strToEncrypt == null) return null;
byte[] iv = new byte[96];
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, iv);
byte[] aadData = "symService".getBytes();
String keyString = "IDeCVaBRGoWE1Xb+X4MdZrq7UXgB3M58m3Xpdk4b+uU=";
SecretKeySpec secretKeySpec = new SecretKeySpec(Base64.getDecoder().decode(keyString), "AES");
Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, gcmParameterSpec, new SecureRandom());
cipher.updateAAD(aadData);
String encryptedText = Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
System.out.println("encryptedText : " + encryptedText);
return encryptedText;
}
public String decrypt(String strToDecrypt) throws Exception {
if(strToDecrypt == null || strToDecrypt.isEmpty()) return null;
byte[] iv = new byte[96];
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, iv);
byte[] aadData = "symService".getBytes();
String keyString = "IDeCVaBRGoWE1Xb+X4MdZrq7UXgB3M58m3Xpdk4b+uU=";
SecretKeySpec secretKeySpec = new SecretKeySpec(Base64.getDecoder().decode(keyString), "AES");
Cipher cipher = Cipher.getInstance("AES/GCM/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, gcmParameterSpec, new SecureRandom());
cipher.updateAAD(aadData);
String decryptedText = new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt)));
System.out.println("decryptedText : " + decryptedText);
return decryptedText;
}
Cipher
This class provides the functionality of a cryptographic cipher for encryption and decryption. It forms the core of the Java Cryptographic Extension (JCE) framework.
GCM
GCM is an authenticated encryption mode with "additional data" (often referred to as AEAD). GCM is a cipher mode that can be applied to any symmetric encryption algorithm with 16-byte block size, such as AES and Twofish.
PKCS5Padding
This is a padding scheme described in RSA Laboratories, "PKCS #5: Password-Based Encryption Standard," version 1.5.