sun.misc.BASE64 to apache commons - java

I have a simple code here, the code uses the sun.misc.BASE64Encoder and sun.misc.BASE64Decoder, which are not available in Eclipse Java 7.0 , I wanted to make the code such that it uses the Apache commons base 64 and still do exactly the same thing,
The variables
private static final String ALGORITHM = "AES";
private static final byte[] keyValue = "2H5a1r5i6s3h8C1h".getBytes();
Original Code
public static String AESencrypt(String valueToEnc) throws Exception {
Key key = new SecretKeySpec(keyValue, ALGORITHM);
Cipher c = Cipher.getInstance(ALGORITHM);
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encValue = c.doFinal(valueToEnc.getBytes());
String encryptedValue = new BASE64Encoder().encode(encValue);
return encryptedValue;
}
public static String AESdecrypt(String encryptedValue) throws Exception {
Key key = new SecretKeySpec(keyValue, ALGORITHM);
Cipher c = Cipher.getInstance(ALGORITHM);
c.init(Cipher.DECRYPT_MODE, key);
byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedValue);
byte[] decValue = c.doFinal(decordedValue);
String decryptedValue = new String(decValue);
return decryptedValue;
}
Trying to modify to apache commons code
public static String AESencrypt(String valueToEnc) throws Exception {
Key key = new SecretKeySpec(keyValue, ALGORITHM);
Cipher c = Cipher.getInstance(ALGORITHM);
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encValue = c.doFinal(valueToEnc.getBytes());
String encryptedValue = new Base64().encodeBase64(encValue).toString();
return encryptedValue;
}
public static String AESdecrypt(String encryptedValue) throws Exception {
Key key = new SecretKeySpec(keyValue, ALGORITHM);
Cipher c = Cipher.getInstance(ALGORITHM);
c.init(Cipher.DECRYPT_MODE, key);
byte[] decordedValue = new Base64().decodeBase64(encryptedValue);
byte[] decValue = c.doFinal(decordedValue);
String decryptedValue = new String(decValue);
return decryptedValue;
}
The original code works fine, the new code throws the following exception,
Exception in thread "main" javax.crypto.IllegalBlockSizeException:
Input length must be multiple of 16 when decrypting with padded cipher
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:750)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
at
com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313)
at javax.crypto.Cipher.doFinal(Cipher.java:2087) at
trial2.encrypt.AESdecrypt(encrypt.java:28) at
trial2.encrypt.main(encrypt.java:37)
Java Result: 1
How can I solve this problem without altering the initial code too much, a few lines here and there are OK. Is it possible to completely eliminate the Base64encoding step and make it work with only the ciphers like this:
public static String AESencrypt(String valueToEnc) throws Exception {
Key key = new SecretKeySpec(keyValue, ALGORITHM);
Cipher c = Cipher.getInstance(ALGORITHM);
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encValue = c.doFinal(valueToEnc.getBytes());
return encValue.toString();
}
public static String AESdecrypt(String encryptedValue) throws Exception {
Key key = new SecretKeySpec(keyValue, ALGORITHM);
Cipher c = Cipher.getInstance(ALGORITHM);
c.init(Cipher.DECRYPT_MODE, key);
byte[] decValue = c.doFinal(encryptedValue.getBytes());
String decryptedValue = new String(decValue);
return decryptedValue;
}
The above code has similar exception like the second code:
Exception in thread "main" javax.crypto.IllegalBlockSizeException:
Input length must be multiple of 16 when decrypting with padded cipher
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:750)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
at
com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313)
at javax.crypto.Cipher.doFinal(Cipher.java:2087) at
trial2.encrypt.AESdecrypt(encrypt.java:26) at
trial2.encrypt.main(encrypt.java:35) Java Result: 1
Please help and TYVM

The error is in your encrypt method. The following code is wrong:
byte[] encValue = c.doFinal(valueToEnc.getBytes());
String encryptedValue = new Base64().encodeBase64(encValue).toString();
You are calling toString() on a byte array, which won't do what you want! Instead, try:
byte[] encValue = c.doFinal(valueToEnc.getBytes());
String encryptedValue = Base64.encodeBase64String(encValue);
This should then work correctly.

Related

Exception in thread "main" java.security.InvalidKeyException: Illegal key size. char length of key is 44

Exception in thread "main" java.security.InvalidKeyException: Illegal key size for below code
Char length of the key is 44. I tried with char length 24 am able to encrypt. Please help how to resolve this issue.
public static void main(String args[]) throws Exception {
String plainText = "Hello world!";
String encryptionKeyBase64 = "DWIzFkO22qfVMgx2fIsxOXnwz10pRuZfFJBvf4RS3eY=";
System.out.println(encryptionKeyBase64.length());
String ivBase64 = "AcynMwikMkW4c7+mHtwtfw==";
EncDec encDec = new EncDec();
String cipherText = encDec.encrypt(plainText, encryptionKeyBase64, ivBase64);
}
public String encrypt(String plainText, String keyBase64, String ivBase64) throws Exception
{
byte[] plainTextArray = plainText.getBytes(StandardCharsets.UTF_8);
byte[] keyArray = DatatypeConverter.parseBase64Binary(keyBase64);
byte[] iv = DatatypeConverter.parseBase64Binary(ivBase64);
SecretKeySpec secretKey = new SecretKeySpec(keyArray, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv));
return new String(DatatypeConverter.printBase64Binary(cipher.doFinal(plainTextArray)));
}
public String decrypt(String messageBase64, String keyBase64, String ivBase64) throws Exception {
byte[] messageArray = DatatypeConverter.parseBase64Binary(messageBase64);
byte[] keyArray = DatatypeConverter.parseBase64Binary(keyBase64);
byte[] iv = DatatypeConverter.parseBase64Binary(ivBase64);
SecretKey secretKey = new SecretKeySpec(keyArray, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv));
return new String(cipher.doFinal(messageArray));
}
}```
As you are using "AES" as encryption-scheme the key lengths must be 16, 24 or 32 bytes in the input of SecretKeySpec.
So you should check the length of the byte[] keyArray and not the length of your String "encryptionKeyBase64" and make sure it's of 16/24/32 byte length.
You can add the line
System.out.println("keyArray.length: " +
DatatypeConverter.parseBase64Binary(encryptionKeyBase64).length);
before you're using it in your encryption-/decryption method.
Btw.: the initialisation vector "iv" has to be of 16 bytes length (fixed, regardless of key length). You can check that easily with
System.out.println("iv.length: " + DatatypeConverter.parseBase64Binary(ivBase64).length);

Triple DES encryption string generates "\n"

While encrypting a string, it generates '\n' at end of the string.
This is how I'm doing encryption
public static String encrypt(String plainText) throws Exception {
byte[] tdesKeyData = Consts.getSecretKey().getBytes();
byte[] myIV = Consts.getInitializationVector().getBytes();
SecretKeySpec myKey = new SecretKeySpec(tdesKeyData, "DES");
IvParameterSpec ivspec = new IvParameterSpec(myIV);
Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS7Padding");
cipher.init(Cipher.ENCRYPT_MODE, myKey, ivspec);
byte[] plainTextBytes = plainText.getBytes("UTF-8");
byte[] buf = cipher.doFinal(plainTextBytes);
byte[] base64Bytes = Base64.encode(buf, Base64.DEFAULT);
String base64EncryptedString = new String(base64Bytes);
return base64EncryptedString;
}
Please, somebody, guide me, what am I doing wrong here? Thanks in Advance.
Base64.NO_WRAP
Encoder flag bit to omit all line terminators (i.e., the output will be on one long line).

How to decrypt a text?

I am developing an application, where I am encrypting and decrypting a text entered by the user.
But, I am getting the following error:
javax.crypto.IllegalBlockSizeException: last block incomplete in
decryption
below is my code for encryption and decryption. Encryption works perfectly, while I am getting this error while decrypting. Please refer the code below:
public static String fncEncrypt(String strClearText, String strKey) throws Exception{
String strData = "";
try {
SecretKeySpec sKeySpec = new SecretKeySpec(strKey.getBytes(), "Blowfish");
Cipher cipher = Cipher.getInstance("Blowfish");
cipher.init(Cipher.ENCRYPT_MODE, sKeySpec);
byte[] encrypted = cipher.doFinal(strClearText.getBytes());
strData = new String(encrypted);
}catch (Exception e){
e.printStackTrace();
}
return strData;
}
public static String fncDecrypt(String strEecrypted, String strKey) throws Exception {
String strData = "";
try {
SecretKeySpec skeySpec = new SecretKeySpec(strKey.getBytes(), "Blowfish");
Cipher cipher = Cipher.getInstance("Blowfish");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(strEecrypted.getBytes());
strData = new String(decrypted);
}catch (Exception e){
e.printStackTrace();
}
return strData;
}
Please respond if you have a solution for this.
You should decode the string instead of encoding the platform specific representation of the string, right at the start of your method.
byte[] base64TextToDecrypt = Base64.decodeBase64(textToDecrypt);
or more precisely:
byte[] bytesToDecrypt = Base64(base64TextToDecrypt);
if you name your variables correctly.
In general, each time you (feel like you have to) use the String.getBytes(): byte[] method or the String(byte[]) constructor you are likely doing something wrong. You should first think about what you are trying to do, and specify a character-encoding if you do need to use it.
In your case, the output in the converted variable is probably character-encoded. So you you could use the following fragment:
String plainText = new String(converted, Charset.forName("UTF8"));
System.out.println(plainText);
instead of what you have now.
Reference : https://stackoverflow.com/a/13274072/8416317
String class method getBytes() or new String(byte bytes[]) encode / decode with Charset.defaultCharset().name(), and some encrypted data would be ignored by encoding with special charset.
you could directly return byte[] by fncEncrypt and input byte[] to fncDecrypt. or encode result with BASE64.
public static byte[] fncEncrypt(String strClearText, String strKey) throws Exception{
byte[] encrypted = null;
try {
SecretKeySpec sKeySpec = new SecretKeySpec(strKey.getBytes(), "Blowfish");
Cipher cipher = Cipher.getInstance("Blowfish");
cipher.init(Cipher.ENCRYPT_MODE, sKeySpec);
encrypted = cipher.doFinal(strClearText.getBytes());
} catch (Exception e){
e.printStackTrace();
}
return encrypted;
}
public static String fncDecrypt(byte[] ecrypted, String strKey) throws Exception {
String strData = "";
try {
SecretKeySpec skeySpec = new SecretKeySpec(strKey.getBytes(), "Blowfish");
Cipher cipher = Cipher.getInstance("Blowfish");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(ecrypted);
strData = new String(decrypted);
}catch (Exception e){
e.printStackTrace();
}
return strData;
}
The reason is when you use new String(encrypted) it will not fully encode the bytes to string. Try the code below
public static byte[] fncEncrypt(String strClearText, String strKey) throws Exception{
SecretKeySpec sKeySpec = new SecretKeySpec(strKey.getBytes(), "Blowfish");
Cipher cipher = Cipher.getInstance("Blowfish");
cipher.init(Cipher.ENCRYPT_MODE, sKeySpec);
byte[] encrypted = cipher.doFinal(strClearText.getBytes());
return encrypted;
}
public static String fncDecrypt(byte[] encrypted, String strKey) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(strKey.getBytes(), "Blowfish");
Cipher cipher = Cipher.getInstance("Blowfish");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return new String(decrypted);
}
You can encrypt and decrypt using the code below
String message = "Hello!";
byte[] encrypted = fncEncrypt(message, "key");
String decrypted = fncDecrypt(encrypted, "key");
System.out.println(decrypted);

Review of this AES-128 CBC example with password-based encryption

I need some help validating the below code snippet for Java AES encryption with CBC, PKCS5Padding and IV.
I tested the code and was able to encrypt and decrypt. I have a few queries as described below.
Where should the password be stored as a good convention?
Is the way of appending/retrieving salt and IV bytes to the ciphetext fine?
Any other comments highly appreciated, thanks!
public class Encryption {
private static int iterations = 65536;
private static int keySize = 128;
private static char[] password = "password".toCharArray();
private static String algorithm= "PBKDF2WithHmacSHA1";
private static final String SEPARATOR = "~";
public static void main(String []args) throws Exception {
String filePath = "test.xml";
String fileContent = new String(Files.readAllBytes(Paths.get(filePath)));
String encrMesg = encrypt(fileContent);
System.out.println("Encrypted: " + encrypt(encrMesg));
System.out.println("Decrypted: " + decrypt(encrMesg));
}
public static String encrypt(String plaintext) throws Exception {
byte[] saltBytes = getSalt().getBytes();
SecretKeyFactory skf = SecretKeyFactory.getInstance(algorithm);
PBEKeySpec spec = new PBEKeySpec(password, saltBytes, iterations, keySize);
SecretKey secretKey = skf.generateSecret(spec);
SecretKeySpec secretSpec = new SecretKeySpec(secretKey.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretSpec);
AlgorithmParameters params = cipher.getParameters();
byte[] ivBytes = params.getParameterSpec(IvParameterSpec.class).getIV();
byte[] cipherText = cipher.doFinal(String.valueOf(plaintext).getBytes("UTF-8"));
return DatatypeConverter.printBase64Binary(ivBytes)+SEPARATOR+DatatypeConverter.printBase64Binary(saltBytes)
+SEPARATOR+DatatypeConverter.printBase64Binary(cipherText);
}
public static String decrypt(String encryptedText) throws Exception {
System.out.println(encryptedText);
String[] encryptedArr = encryptedText.split(SEPARATOR);
byte[] ivBytes = DatatypeConverter.parseBase64Binary(new String(encryptedArr[0]));
byte[] salt = DatatypeConverter.parseBase64Binary(new String(encryptedArr[1]));
byte[] encryptedTextBytes = DatatypeConverter.parseBase64Binary(new String(encryptedArr[2]));
SecretKeyFactory skf = SecretKeyFactory.getInstance(algorithm);
PBEKeySpec spec = new PBEKeySpec(password, salt, iterations, keySize);
SecretKey secretKey = skf.generateSecret(spec);
SecretKeySpec secretSpec = new SecretKeySpec(secretKey.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretSpec, new IvParameterSpec(ivBytes));
byte[] decryptedTextBytes = null;
try {
decryptedTextBytes = cipher.doFinal(encryptedTextBytes);
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return new String(decryptedTextBytes);
}
public static String getSalt() throws Exception {
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
byte[] salt = new byte[20];
sr.nextBytes(salt);
return new String(salt);
}
}
Queries
Where should the password be stored as a good convention?
Symmetric keys should go preferably to a vault. Otherwise they should go on a keystore, but then you have the issue of securing the keystore password.
Is the way of appending/retrieving Salt and IV bytes to the Cipher
text is fine?
Salt should be generated with:
SecureRandom random = SecureRandom.getInstanceStrong();
Otherwise you are using weaker entropy pools (i.e. /dev/urandom in linux) to generate your secure numbers, and that leads to weak keys that can be more easily broken.
Any other comments highly appreciated, thanks!
You should consistently use the same encoding when dealing with String conversion, i.e., .getBytes("UTF-8") to avoid issues. You don't use it when converting the salt for example.

Java AES encryption and decryption with static secret

I have an application that needs to store some secret passwords in a configuration file such as database and ftp passwords/detail. I've looked around and found a lot of encryption/decryption solutions using AES, but I can't seem to figure out how to make it work without changing the key. That means I can encrypt and decrypt (using the same SecretKey), but to maintain persistence across restarts etc. I can't seem to make the SecretKey stay the same. The example below shows my methods working:
String secret = Encryptor.encrpytString("This is secret");
String test = Encryptor.decrpytString(secret);
System.out.println(test); //This is secret is printed
So far so good. However if I run it once I might get the value of '2Vhht/L80UlQ184S3rlAWw==' as my secret, the next time it is 'MeC4zCf9S5wUUKAu8rvpCQ==', so presumably the key is changing. I'm assuming I am applying some counter-intuative logic to the problem and would appreciate if someone can shed some light on either a) what I'm doing wrong, or b) a solution that would allow me to store the password information encrypted and retrievable with the information provided.
My methods are as follows:
private static final String salt = "SaltySalt";
private static byte [] ivBytes = null;
private static byte[] getSaltBytes() throws Exception {
return salt.getBytes("UTF-8");
}
private static char[] getMasterPassword() {
return "SuperSecretPassword".toCharArray();
}
private static byte[] getIvBytes() throws Exception {
if (ivBytes == null) {
//I don't have the parameters, so I'll generate a dummy encryption to create them
encrpytString("test");
}
return ivBytes;
}
public static String encrpytString (String input) throws Exception {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(getMasterPassword(), getSaltBytes(), 65536,256);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
ivBytes = cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
byte[] encryptedTextBytes = cipher.doFinal(input.getBytes("UTF-8"));
return DatatypeConverter.printBase64Binary(encryptedTextBytes);
}
public static String decrpytString (String input) throws Exception {
byte[] encryptedTextBytes = DatatypeConverter.parseBase64Binary(input);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(getMasterPassword(), getSaltBytes(), 65536, 256);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(getIvBytes()));
byte[] decryptedTextBytes = cipher.doFinal(encryptedTextBytes);
return new String(decryptedTextBytes);
}
Thanks for the help!
OK, looks like I've found the answer to my question. I sourced my information from this Stackoverflow post.
From what I understand, the IV (initialisation vector) is used to add entropy into the encryption process. Each time you create a new cipher, Java creates a slightly different IV. There are therefore two solutions:
User a fixed IV, or
Store the IV along with the encrypted data.
From what I've read, option 1 is not very good practice; so option 2 it is. I understand that it should be possible to simply append the IV to the encrypted string (as the secret is still required) and therefore the IV can be reconstructed when it comes time to decrypt.
Here is the almost complete solution. I'm still getting some padding errors on decryption (see my comment). I don't have time to spend on it now, so as a temporary measure I immediately try decrypting an encrypted string and keep on trying (iterating) until it works. It seems to have about a 50% hit rate + I'm not encrypting often enough for it to be a performance concern. Would be nice if someone could suggest a fix though (just for completeness sake).
private static final String salt = "SaltySalt";
private static final int IV_LENGTH = 16;
private static byte[] getSaltBytes() throws Exception {
return salt.getBytes("UTF-8");
}
private static char[] getMasterPassword() {
return "SuperSecretPassword".toCharArray();
}
public static String encrpytString (String input) throws Exception {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(getMasterPassword(), getSaltBytes(), 65536,256);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
byte[] ivBytes = cipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
byte[] encryptedTextBytes = cipher.doFinal(input.getBytes("UTF-8"));
byte[] finalByteArray = new byte[ivBytes.length + encryptedTextBytes.length];
System.arraycopy(ivBytes, 0, finalByteArray, 0, ivBytes.length);
System.arraycopy(encryptedTextBytes, 0, finalByteArray, ivBytes.length, encryptedTextBytes.length);
return DatatypeConverter.printBase64Binary(finalByteArray);
}
public static String decrpytString (String input) throws Exception {
if (input.length() <= IV_LENGTH) {
throw new Exception("The input string is not long enough to contain the initialisation bytes and data.");
}
byte[] byteArray = DatatypeConverter.parseBase64Binary(input);
byte[] ivBytes = new byte[IV_LENGTH];
System.arraycopy(byteArray, 0, ivBytes, 0, 16);
byte[] encryptedTextBytes = new byte[byteArray.length - ivBytes.length];
System.arraycopy(byteArray, IV_LENGTH, encryptedTextBytes, 0, encryptedTextBytes.length);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(getMasterPassword(), getSaltBytes(), 65536, 256);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivBytes));
byte[] decryptedTextBytes = cipher.doFinal(encryptedTextBytes);
return new String(decryptedTextBytes);
}
Use a static Initialization Vector, e.g. a zero IV:
cipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(new byte[16]));
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(new byte[16]));
Since you're storing passwords you probably want to use a random IV and/or random salt and store them with the cipher text so the same passwords don't encrypt to the same ciphertext.
You need to setSeed() before
class Encryptor {
static final String salt = "SaltSalt";
public static byte[] encryptString(String input) throws Exception {
byte[] bytes = input.getBytes("UTF-8");
Cipher cipher = Cipher.getInstance("AES");
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = new SecureRandom();
secureRandom.setSeed(salt.getBytes("UTF-8"));
keyGenerator.init(256, secureRandom);
Key key = keyGenerator.generateKey();
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] a = cipher.doFinal(bytes);
return a;
}
public static String decryptString(byte[] input) throws Exception {
Cipher cipher = Cipher.getInstance("AES");
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
SecureRandom secureRandom = new SecureRandom();
secureRandom.setSeed(salt.getBytes("UTF-8"));
keyGenerator.init(256, secureRandom);
Key key = keyGenerator.generateKey();
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] decrypted = cipher.doFinal(input);
String result = new String(decrypted, "UTF-8");
return result;
}
}

Categories