Click here to Skip to main content
15,881,173 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Currently I'm having a problem that I don't know how to solve. It's the decryption and encryption of the string using AES256. Everything was working fine until I restarted the server and I couldn't decode the previous data. Hope everyone can help me. Thank you very much.


What I have tried:

private static final String SECRET_KEY = "my_key";
private static final byte[] SALT;
private static final SecureRandom random;
private static final IvParameterSpec ivspec;

static {
    random = new SecureRandom();
    SALT = new byte[16];
    random.nextBytes(SALT);
    byte[] bytesIV = new byte[16];
    random.nextBytes(bytesIV);
    ivspec = new IvParameterSpec(bytesIV);
}

public static String encrypt(String stringToEncrypt) {
    try {
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        KeySpec spec = new PBEKeySpec(SECRET_KEY.toCharArray(), SALT, 65536, 256);
        SecretKey tmp = factory.generateSecret(spec);
        SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES");

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivspec);
        return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes(StandardCharsets.UTF_8)));
    } catch (Exception e) {
        System.out.println("Error while encrypting: " + e);
    }
    return null;
}

public static String decrypt(String stringToDecrypt) {
    try {
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        KeySpec spec = new PBEKeySpec(SECRET_KEY.toCharArray(), SALT, 65536, 256);
        SecretKey tmp = factory.generateSecret(spec);
        SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES");

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        cipher.init(Cipher.DECRYPT_MODE, secretKey, ivspec);
        return new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt)));
    } catch (Exception e) {
        System.out.println("Error while decrypting: " + e);
    }
    return null;
}
Posted
Updated 9-Aug-21 20:04pm

1 solution

You are using a random number generator to produce your IV when you encrypt your data : unless that exact IV is used when you decrypt it, what you will get is nonsense.

So every time your app is closed, the current IV is discarded and when it is restarted, you get a new random IV value - that means your encrypted data is no longer recoverable (except in some encryption systems, where all but the first block is recoverable: encryption - Can CBC ciphertext be decrypted if the key is known, but the IV not? - Cryptography Stack Exchange[^]

Store your IV as part of the encrypted data!
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900