Dariko77
Dariko77

Reputation: 141

How to decrypt a String using PBE algorithm

I have a PBE-generated secret key and I ciphered a string using the algorithm "PBEWithHmacSHA256AndAES_128" however I'm unable to decipher the said string.

Secret key generate:

private final static byte[] SALT = { (byte) 0xc9, (byte) 0x36, (byte) 0x78, (byte) 0x99, (byte) 0x52, (byte) 0x3e, (byte) 0xea,
        (byte) 0xf2 };

PBEKeySpec keySpec = new PBEKeySpec(pwd.toCharArray(), SALT, 20 , 128);     
    try {
        SecretKeyFactory kf = SecretKeyFactory.getInstance("PBEWithHmacSHA256AndAES_128");
        PRIVATE_KEY = kf.generateSecret(keySpec);
    } catch (NoSuchAlgorithmException | InvalidKeySpecException  e) {
        e.printStackTrace();
    }

Encypt String:

private static String cipherString(String string) {


    PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(SALT, 100);
    Cipher cipher;
    try {
        cipher = Cipher.getInstance("PBEWithHmacSHA256AndAES_128");
        cipher.init(Cipher.ENCRYPT_MODE, PRIVATE_KEY, pbeParameterSpec);
        byte[] input = string.getBytes();
        byte[] encryptedp = cipher.doFinal(input);

        return encryptedp.toString();
    } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

Decrypt String:

private static String decipherString(String string) {
    Cipher c;
    try {
        c = Cipher.getInstance("PBEWithHmacSHA256AndAES_128");

        c.init(Cipher.DECRYPT_MODE, PRIVATE_KEY);

        byte[] input = string.getBytes();
        byte[] encryptedp = c.doFinal(input);

        return encryptedp.toString();

    } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;
}

Upvotes: 0

Views: 5661

Answers (1)

JMax
JMax

Reputation: 1202

Just use the following code that works on J2SE. As the algorithm PBEWithHmacSHA256AndAES_128 uses AES in CBC mode internally we also have to provide an IV, which is my example generated randomly. You have to use the same IV for encryption as well as decryption. For security reasons for each encryption you should use a new random IV and save it together with the encrypted text.

    SecureRandom rnd = new SecureRandom();
    byte[] iv = new byte[16];
    rnd.nextBytes(iv);
    
    String password = "password";
    byte[] plaintext = "plaintext".getBytes(StandardCharsets.UTF_8);

    IvParameterSpec ivParamSpec = new IvParameterSpec(iv);
    PBEParameterSpec pbeParamSpec = new PBEParameterSpec(SALT, 10000, ivParamSpec);
    PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
    try {
        SecretKeyFactory kf = SecretKeyFactory.getInstance("PBEWithHmacSHA256AndAES_128");
        SecretKey secretKey = kf.generateSecret(keySpec);

        // On J2SE the SecretKeyfactory does not actually generate a key, it just wraps the password.
        // The real encryption key is generated later on-the-fly when initializing the cipher
        System.out.println(new String(secretKey.getEncoded()));

        // Encrypt
        Cipher enc = Cipher.getInstance("PBEWithHmacSHA256AndAES_128");
        enc.init(Cipher.ENCRYPT_MODE, secretKey, pbeParamSpec);
        byte[] encrypted = enc.doFinal(plaintext);
        String encryptedBase64 = new BASE64Encoder().encode(encrypted);
        System.out.println("Encrypted text: " + encryptedBase64);

        // Decrypt
        Cipher dec = Cipher.getInstance("PBEWithHmacSHA256AndAES_128");
        dec.init(Cipher.DECRYPT_MODE, secretKey, pbeParamSpec);
        byte[] decrypted = dec.doFinal(new BASE64Decoder().decode(encryptedBase64));
        String message = new String(decrypted, StandardCharsets.UTF_8);
        
        System.out.println(message);

    } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
        e.printStackTrace();
    }

Upvotes: 2

Related Questions