Created
June 20, 2023 11:26
-
-
Save robsonkades/ec64d24bad691d28fe6d55ce2a40ff64 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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