Skip to content

Instantly share code, notes, and snippets.

@rhobro
Last active January 10, 2021 20:17
Show Gist options
  • Save rhobro/716a23e15f83969071b3bdc0a02e3483 to your computer and use it in GitHub Desktop.
Save rhobro/716a23e15f83969071b3bdc0a02e3483 to your computer and use it in GitHub Desktop.
Java class to encrypt/decrypt strings using the AES 256 bit encryption algorithm
package tech.neurobyte.dev.crypt;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
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;
import java.nio.charset.StandardCharsets;
import java.security.spec.KeySpec;
import java.util.Base64;
public class AES256Crypt {
// Member fields
// The salt for the encryption which will be the username encrypted in DES
private static final String cryptSalt = "NeuroByte Tech";
// The Cipher which will be used to encrypt
private Cipher enCipher;
// The Cipher which will be used to decrypt
private Cipher deCipher;
// The random string key for the person which will be used to encrypt and decrypt details.
private String securiKey;
/**
* The default constructor for the AES256Crypt class
*/
public AES256Crypt() throws Exception {
// Initialize the Cipher objects to encrypt and decrypt using the AES algorithm
this.enCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
this.deCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// Initialize the securiKey
this.securiKey = this.randSecuriKey();
// Creating the initialization vector for the secret key
byte[] initVector = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
IvParameterSpec initVectorSpec = new IvParameterSpec(initVector);
// Setting up the secret key spec with AES
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec pbeKeySpec = new PBEKeySpec(this.securiKey.toCharArray(), cryptSalt.getBytes(), 65536, 256);
SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getEncoded(), "AES");
// Initialize the cipher objects with the keys
this.enCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, initVectorSpec);
this.deCipher.init(Cipher.DECRYPT_MODE, secretKeySpec, initVectorSpec);
}
/**
* Constructor for the AES256Crypt class with the option to use the securiKey from the database.
*
* @param userSecuriKey - The securiKey stored individually for each user on the database
*/
@Contract(pure = true)
AES256Crypt(String userSecuriKey) throws Exception {
// Initialize the Cipher objects to encrypt and decrypt using the AES algorithm
this.enCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
this.deCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// Initialize the securiKey
this.securiKey = userSecuriKey;
// Creating the initialization vector for the secret key
byte[] initVector = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
IvParameterSpec initVectorSpec = new IvParameterSpec(initVector);
// Setting up the secret key spec with AES
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec pbeKeySpec = new PBEKeySpec(this.securiKey.toCharArray(), cryptSalt.getBytes(), 65536, 256);
SecretKey secretKey = secretKeyFactory.generateSecret(pbeKeySpec);
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getEncoded(), "AES");
// Initialize the cipher objects with the keys
this.enCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, initVectorSpec);
this.deCipher.init(Cipher.DECRYPT_MODE, secretKeySpec, initVectorSpec);
}
/**
* Method to encrypt the given string using the AES256 algorithm
*
* @param stringToEncrypt - The string which has to be encrypted
* @return The encrypted string
*/
String encrypt(@NotNull String stringToEncrypt) throws Exception {
// Encoding the string into a sequence of bytes using UTF8 and storing the result into a new byte array.
byte[] stringToEncryptBytes = stringToEncrypt.getBytes(StandardCharsets.UTF_8);
byte[] encryptedStringBytes = this.enCipher.doFinal(stringToEncryptBytes);
// Convert the encryptedString bytes to a String object
// Returning encrypted String
return Base64.getEncoder().encodeToString(encryptedStringBytes);
}
/**
* Method to decrypt the given cipher using the AES256 algorithm
*
* @param cipherToDecrypt - The cipher which has to be decrypted
* @return The decrypted string
*/
@Nullable
String decrypt(@NotNull String cipherToDecrypt) throws Exception {
// Decoding the cipher using BASE64 and deciphering the bytes
byte[] cipherToDecryptBytes = Base64.getDecoder().decode(cipherToDecrypt.getBytes());
byte[] decryptedCipherBytes = this.deCipher.doFinal(cipherToDecryptBytes);
// Return the deciphered String after formatting in UTF8
return new String(decryptedCipherBytes, StandardCharsets.UTF_8);
}
/**
* A method to build a securiKey using random Alpha-Numeric characters
*
* @return A SecuriKey of random Alpha-Numeric characters
*/
@NotNull
private String randSecuriKey() {
// Preparation
// The list of Alpha-numeric characters that will be used to create the random string
final String ALPHA_NUMERIC_STRING = Cortex.configCatClient.getValue(String.class, "aes256cryptListOfEncryptionCharacters", Cortex.databaseManager.getConfigCatUser(), "Default");
// The length of the securiKey
int securiKeyLength = Cortex.configCatClient.getValue(Integer.class, "aes256cryptSecurikeyLength", Cortex.databaseManager.getConfigCatUser(), 0);
StringBuilder randStringBuilder = new StringBuilder();
while (securiKeyLength-- != 0) {
int character = (int) (Math.random() * ALPHA_NUMERIC_STRING.length());
randStringBuilder.append(ALPHA_NUMERIC_STRING.charAt(character));
}
return randStringBuilder.toString();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment