Last active
November 22, 2021 09:50
-
-
Save robbdimitrov/7e29a33c50b78e5836db32e09e64cba4 to your computer and use it in GitHub Desktop.
Symmetric AES encryption with Java
This file contains 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
package com.robbdimitrov.crypto; | |
import java.io.ByteArrayOutputStream; | |
import java.io.IOException; | |
import java.security.NoSuchAlgorithmException; | |
import java.security.SecureRandom; | |
import java.util.Arrays; | |
import java.util.Base64; | |
import javax.crypto.Cipher; | |
import javax.crypto.KeyGenerator; | |
import javax.crypto.SecretKey; | |
import javax.crypto.spec.IvParameterSpec; | |
import javax.crypto.spec.SecretKeySpec; | |
public class Crypto { | |
public static String generateKey() { | |
try { | |
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); | |
keyGenerator.init(256); | |
SecretKey secretKey = keyGenerator.generateKey(); | |
return Base64.getEncoder().encodeToString(secretKey.getEncoded()); | |
} catch (NoSuchAlgorithmException e) { | |
e.printStackTrace(); | |
} | |
return null; | |
} | |
public static String encrypt(String value, String secret) { | |
SecretKey secretKey = decodeKey(secret); | |
try { | |
IvParameterSpec ivspec = generateIv(); | |
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); | |
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivspec); | |
byte[] cipherText = cipher.doFinal(value.getBytes()); | |
byte[] data = concat(ivspec.getIV(), cipherText); | |
return Base64.getEncoder().encodeToString(data); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
return null; | |
} | |
public static String decrypt(String value, String secret) { | |
SecretKey secretKey = decodeKey(secret); | |
try { | |
byte[] data = Base64.getDecoder().decode(value); | |
IvParameterSpec ivspec = new IvParameterSpec(Arrays.copyOfRange(data, 0, 16)); | |
byte[] cipherText = Arrays.copyOfRange(data, 16, data.length); | |
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); | |
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivspec); | |
byte[] plainText = cipher.doFinal(cipherText); | |
return new String(plainText); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
return null; | |
} | |
private static SecretKey decodeKey(String encodedKey) { | |
byte[] decodedKey = Base64.getDecoder().decode(encodedKey); | |
return new SecretKeySpec(decodedKey, 0, decodedKey.length, "AES"); | |
} | |
private static IvParameterSpec generateIv() { | |
byte[] iv = new byte[16]; | |
new SecureRandom().nextBytes(iv); | |
return new IvParameterSpec(iv); | |
} | |
private static byte[] concat(byte[] first, byte[] second) throws IOException { | |
ByteArrayOutputStream output = new ByteArrayOutputStream(); | |
output.write(first); | |
output.write(second); | |
return output.toByteArray(); | |
} | |
} |
This file contains 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
package com.robbdimitrov.crypto; | |
import static org.junit.Assert.assertEquals; | |
import static org.junit.Assert.assertNotEquals; | |
import static org.junit.Assert.assertNotNull; | |
import com.robbdimitrov.crypto.Crypto; | |
import org.junit.Test; | |
public class CryptoTest { | |
@Test | |
public void testGenerateKey() { | |
String secret = Crypto.generateKey(); | |
assertNotNull(secret); | |
assertNotEquals(secret.length(), 0); | |
System.out.print("Secret = " + secret); | |
} | |
@Test | |
public void testEncryption() { | |
String secret = Crypto.generateKey(); | |
String plainText = "Text to be encrypted"; | |
String encrypted = Crypto.encrypt(plainText, secret); | |
assertNotNull(encrypted); | |
assertNotEquals(encrypted, plainText); | |
String decrypted = Crypto.decrypt(encrypted, secret); | |
assertEquals(decrypted, plainText); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment