Java Android, error when decoding AES-256

atereshkov

I'm trying to decrypt some text and I get an error:

javax.crypto.BadPaddingException: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt com.android.org.conscrypt.NativeCrypto.EVP_CipherFinal_ex(Native Method) com.android.org.conscrypt.OpenSSLCipher.doFinalInternal(OpenSSLCipher.java:430) com.android.org.conscrypt.OpenSSLCipher.engineDoFinal(OpenSSLCipher.java:466)javax.crypto.Cipher.doFinal(Cipher.java:1340)

import android.util.Base64;

import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

public class AESEncrypter {

    private static final byte[] SALT = {
            (byte) 0xA9, (byte) 0x9B, (byte) 0xC8, (byte) 0x32,
            (byte) 0x56, (byte) 0x35, (byte) 0xE3, (byte) 0x03
    };
    private static final int ITERATION_COUNT = 65536;
    private static final int KEY_LENGTH = 256;
    private Cipher ecipher;
    private Cipher dcipher;

    public AESEncrypter(String passPhrase) throws Exception {
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        KeySpec spec = new PBEKeySpec(passPhrase.toCharArray(), SALT, ITERATION_COUNT, KEY_LENGTH);
        SecretKey tmp = factory.generateSecret(spec);
        SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

        ecipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // "AES/CBC/NoPadding"
        ecipher.init(Cipher.ENCRYPT_MODE, secret);

        dcipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        byte[] iv = ecipher.getParameters().getParameterSpec(IvParameterSpec.class).getIV();
        dcipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
    }

    public String encrypt(String encrypt) throws Exception {
        encrypt = encrypt.replace("\n", "");

        byte[] bytes = encrypt.getBytes("UTF8");
        byte[] encrypted = encrypt(bytes);
        return Base64.encodeToString(encrypted, Base64.DEFAULT);
    }

    public byte[] encrypt(byte[] plain) throws Exception {
        return ecipher.doFinal(plain);
    }

    public String decrypt(String encrypt) throws Exception {
        encrypt = encrypt.replace("\n", "");
        byte[] bytes = Base64.decode(encrypt, Base64.DEFAULT);
        byte[] decrypted = decrypt(bytes);
        return new String(decrypted, "UTF8");
    }

    public byte[] decrypt(byte[] encrypt) throws Exception {
        return dcipher.doFinal(encrypt);
    }

}

Any suggestions?

Artjom B.

This answer is a complete shot in the dark, but it is plausible.

Problem:

Currently, you're retrieving the IV as a byte array from the Cipher instance for encryption and passing the same byte array to the Cipher instance for decryption. The problem might be that this IV is not actually copied and will reflect the state of the execution of the encryption procedure. A common CBC implementation might use the byte array that is supposed to be the IV as a state for the encryption of every block. This state would change after encryption.

Thus, if the decryption works on a wrong IV and the original plaintext was shorter than 16 bytes, this will likely (~255 in 256) lead to a BadPaddingException. If the plaintext is 16 bytes or longer, then you will not see a BadPaddingException, but the first 16 bytes will look like garbage. I suggest that you look into how CBC mode works.

Possible solution:

You need to copy the IV. So this should suffice:

dcipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(Arrays.copyOf(iv, iv.length)));

Proper solution:

Keep in mind that this only works if you encrypt and decrypt during one execution of the program. If you want to decrypt in a different execution, you need to store the IV somehow.

Since the IV does not need to be secret, it can be sent along with the ciphertext. It is customary to prepend it to the ciphertext and slice it off before decryption.

The salt should also be random and you can send it along with the ciphertext in the same way as the IV.


Security consideration:

The ciphertext is not authenticated. Thus, you cannot detect (malicious) manipulation. It is best to use authenticated modes like GCM/EAX or use an encrypt-then-MAC scheme with a strong MAC like HMAC-SHA256.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Java Android, error when decoding AES-256

From Dev

Java, error when decoding AES-256

From Dev

Java AES 256 encryption

From Dev

Link error when using AES256 example with OpenSSL

From Dev

teamcity aes256-cbc error when retrieving git repository

From Dev

Tag mismatch error in AES-256-GCM Decryption using Java

From Dev

Decoding JSON in Java Android

From Dev

Error when decrypt input data longer than 15 chars with AES256 and Node.js

From Dev

Python AES CBC error with string size when using Block size of 256

From Dev

NodeJS AES 256 hex decrypt error

From Dev

Aes256-cbc encoding/decrypting error

From Dev

java ssl error Cannot support TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

From Dev

How to use 256 bit aes encryption in android

From Dev

Android/Java AES 256 CBC with PKCS5Padding decryption in PHP

From Dev

Android/Java AES 256 CBC with PKCS5Padding decryption in PHP

From Dev

AES 256 encryption - Qt equivalent for Java

From Dev

Decrypt PHP AES-256-CFB in Java

From Dev

Pad block corrupted error decoding Rijndael 256 with BouncyCastle

From Dev

Android Java AES Encryption

From Dev

AES256 Encryption/Decryption Error+ IOS SDK 7

From Dev

AES256 Encryption/Decryption Error+ IOS SDK 7

From Dev

Compilation gcc error undefined reference to `aes256_init'

From Dev

What is the default IV when encrypting with aes_256_cbc cipher?

From Dev

What is the default IV when encrypting with aes_256_cbc cipher?

From Dev

Whats is the Java name for openssl's "aes-256-cfb"?

From Dev

AES-256 and PKCS7Padding fails in Java

From Dev

Pr0blem with AES256 encryption in java

From Dev

Encrypt in java and Decrypt in C# For AES 256 bit

From Dev

AES-256 Password Based Encryption/Decryption in Java

Related Related

  1. 1

    Java Android, error when decoding AES-256

  2. 2

    Java, error when decoding AES-256

  3. 3

    Java AES 256 encryption

  4. 4

    Link error when using AES256 example with OpenSSL

  5. 5

    teamcity aes256-cbc error when retrieving git repository

  6. 6

    Tag mismatch error in AES-256-GCM Decryption using Java

  7. 7

    Decoding JSON in Java Android

  8. 8

    Error when decrypt input data longer than 15 chars with AES256 and Node.js

  9. 9

    Python AES CBC error with string size when using Block size of 256

  10. 10

    NodeJS AES 256 hex decrypt error

  11. 11

    Aes256-cbc encoding/decrypting error

  12. 12

    java ssl error Cannot support TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

  13. 13

    How to use 256 bit aes encryption in android

  14. 14

    Android/Java AES 256 CBC with PKCS5Padding decryption in PHP

  15. 15

    Android/Java AES 256 CBC with PKCS5Padding decryption in PHP

  16. 16

    AES 256 encryption - Qt equivalent for Java

  17. 17

    Decrypt PHP AES-256-CFB in Java

  18. 18

    Pad block corrupted error decoding Rijndael 256 with BouncyCastle

  19. 19

    Android Java AES Encryption

  20. 20

    AES256 Encryption/Decryption Error+ IOS SDK 7

  21. 21

    AES256 Encryption/Decryption Error+ IOS SDK 7

  22. 22

    Compilation gcc error undefined reference to `aes256_init'

  23. 23

    What is the default IV when encrypting with aes_256_cbc cipher?

  24. 24

    What is the default IV when encrypting with aes_256_cbc cipher?

  25. 25

    Whats is the Java name for openssl's "aes-256-cfb"?

  26. 26

    AES-256 and PKCS7Padding fails in Java

  27. 27

    Pr0blem with AES256 encryption in java

  28. 28

    Encrypt in java and Decrypt in C# For AES 256 bit

  29. 29

    AES-256 Password Based Encryption/Decryption in Java

HotTag

Archive