Skip to content

Instantly share code, notes, and snippets.

@robsonkades
Created June 20, 2023 11:26
Show Gist options
  • Save robsonkades/ec64d24bad691d28fe6d55ce2a40ff64 to your computer and use it in GitHub Desktop.
Save robsonkades/ec64d24bad691d28fe6d55ce2a40ff64 to your computer and use it in GitHub Desktop.
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
public class CryptoHelper {
private static final byte[] SALT = new byte[16];
private static final String PBKDF_2_WITH_HMAC_SHA_256 = "PBKDF2WithHmacSHA256";
private static final String ALGORITHM = "AES/GCM/NoPadding";
private static final int GCM_IV_LENGTH = 12;
private static final int GCM_TAG_LENGTH = 128;
private static final SecureRandom SECURE_RANDOM = new SecureRandom();
private static final int ITERATION_COUNT = 10000;
private static final int KEY_LENGTH = 256;
private final SecretKeySpec secretKeySpec;
public CryptoHelper(final String password) {
this.secretKeySpec = createSecretKey(password);
}
public byte[] encrypt(byte[] data) {
try {
Cipher cipher = Cipher.getInstance(ALGORITHM);
byte[] iv = new byte[GCM_IV_LENGTH];
SECURE_RANDOM.nextBytes(iv);
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH, iv);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, gcmParameterSpec);
byte[] encrypted = cipher.doFinal(data);
byte[] bytes = new byte[iv.length + encrypted.length];
System.arraycopy(iv, 0, bytes, 0, iv.length);
System.arraycopy(encrypted, 0, bytes, iv.length, encrypted.length);
return bytes;
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException |
InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) {
throw new CryptoException(e);
}
}
public byte[] decrypt(byte[] bytes) {
try {
Cipher cipher = Cipher.getInstance(ALGORITHM);
byte[] iv = new byte[GCM_IV_LENGTH];
byte[] encrypted = new byte[bytes.length - GCM_IV_LENGTH];
System.arraycopy(bytes, 0, iv, 0, iv.length);
System.arraycopy(bytes, iv.length, encrypted, 0, encrypted.length);
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH, iv);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, gcmParameterSpec);
return cipher.doFinal(encrypted);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException |
InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) {
throw new CryptoException(e);
}
}
private static SecretKeySpec createSecretKey(String password) {
try {
char[] passwordChars = password.toCharArray();
PBEKeySpec spec = new PBEKeySpec(passwordChars, CryptoHelper.SALT, CryptoHelper.ITERATION_COUNT, CryptoHelper.KEY_LENGTH);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(PBKDF_2_WITH_HMAC_SHA_256);
byte[] keyBytes = keyFactory.generateSecret(spec).getEncoded();
return new SecretKeySpec(keyBytes, "AES");
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
throw new CryptoException(e);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment