5

Actually i work in a app and have a problem with decrypt AES

i have a error in this line byte[] results = cipher.doFinal(Base64.encode(text.getBytes("UTF-8"), Base64.DEFAULT));

error : error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length

String key = "grnR++15jgNFVmVg61UvQA==";
String data = "vrvwe+9wVhyNJmb/KcLD2K2j9gqkwVFXq0jt0qL7zyHHG2JWpkvr+VpG/QHm6INW01WsBZcpRYYk25bMtjWgLY6dzFNs3WLXZRMnVtIDhjuIfv0sp2RKvhjNLEu3Gscz4sdxYYS6XcLOWAY705Ll48+mA55Ke5WSq71jVR+TCJVT0w2nYZvzviE+N0QwRX5EZjCMjbaH4gpFLr+LsNevkAQ7e7Id4oSvrwqJ3PyUS4mo8OvPcUjKDhQCJc39k2aqBBaZ9O1AuqQqCOWpgy2XW9kacAP8zrcDRO7oNtSbIM0sqIyKS4PGzXiL+hw43hs33d/VO8tvLGHWOE0UvWkQY0QPJqzRDmmWpRTgr0Xt56UxIXjjAmteVlb+TWo3kzRSUQ2Un+ScCfEBHjaNJNShE27zSeXOjkMWpB0jobSMJy6KdR/fqopHmYcWd41DNOz25nkUtQBmBK+x5sqM0dLswL8TKfb7MdIdhqdZaHt7h1CTNpozEwg+A7ZEkcGZ3hcGAwPWkPrg1yoXE5uaeCzdslf4knbXBxIx8ekrBiyUY5BhMPak/7LJm9D64RPQEpdOUTeg2fh9nKShXnr1OdKGrf68H7c/rSincB2uqgEuo9oHaBIIwm0RuUkM/jCjeLmVEE2zIjJE2osk2XQKf4iOlHP12XQOCtITYBZm8jc0OKmjpelFaWNLFheAE/txRk/NSS+qmUcWor1BSXDZAxje0ftwTl0jYz69U3tW9pDm3yooWWU51ORoTpQHqEGLumQyJom3OfsSkQ/T/pEMxY6B3a7TmJ+8u+QJla+ZCHFav5aKL1Ojy7xijYzIlsoVP9m7nDp30oVA8rpI8vYKpUHXUuQPxdVV4/yjvCeRkWT/veQtHpA9OWYDSTQLdRYfOOeQoxg/kGua4HU0RlC8IVgm/iJJnpWJgvdKD0KKmVgwFKmZ1TFg5yMRN4oOPDk4yhtnjPV9VhJU4lHztHw7TG53UWblwieeorD+v94LHySXFAj1tyd4tebgrvFqyuPovT4iP7Xm37KA/LmtrCPiCaBn6g==;

        try {
            Decrypt(data,key);
        } catch (Exception e) {
            e.printStackTrace();
        }

Method

String Decrypt(String text, String key) throws Exception {
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    byte[] keyBytes = Base64.decode(key.getBytes(), Base64.DEFAULT);
    SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
    byte[] b = new byte[keySpec.getEncoded().length];
    System.arraycopy(keySpec.getEncoded(), 0, b, 0, b.length);
    IvParameterSpec ivSpec = new IvParameterSpec(b);
    cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
    byte[] results = cipher.doFinal(Base64.encode(text.getBytes("UTF-8"), Base64.DEFAULT));
    String  decoded = new String(cipher.doFinal(results), "UTF-8");
    return decoded;
}
David Hackro
  • 3,652
  • 6
  • 41
  • 61
  • would you mind posting the encryption code? – nandsito Apr 09 '17 at 18:50
  • i dont have the code encryption,this is a response using web service – David Hackro Apr 09 '17 at 19:12
  • What is the expected plaintext? – vlp Apr 09 '17 at 21:29
  • response is a json @vlp – David Hackro Apr 10 '17 at 02:02
  • @DavidHackro You're doing some wrong things there - building your IV (initialisation vector) from your private key. In fact initialization vector should be independent from the key, and by its nature it's not secret in any way. Read more about it here: http://www.javamex.com/tutorials/cryptography/initialisation_vector.shtml, also this SO thread: http://stackoverflow.com/q/9049789/648313 – Volo Apr 11 '17 at 13:22
  • It might help if you could say where you are getting your `key` and `data` from and walk through the process up until you call your `Decrypt` method. – Cheticamp Apr 14 '17 at 16:47

2 Answers2

3

I took a fresh start on how your decryption routine might work. Take a look at the example below. I made some assumptions about your key and data fields that you will see in the code. It is important that you understand where these fields come from and their format. This code has been tested and is working as a demonstration.

The comments should help walk you through.

As for the error you are seeing, it indicates that your encrypted string is not the right length. Since it seems to be padded, it should be a multiple of 16 bytes (it is not) which is the AES block size. The string you give is missing a terminating quotation mark, so it would not compile anyway. It is hard to say what exactly has happened with the encrypted string.

The initialization vector is not being set up correctly. The iv is independent of the key, is separately derived during encryption and is a "given" during decryption. Take a look at how the initialization vector is set up in the following routine.

I hope this helps.

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        final String SECRET_KEY = "PloasdlOoasdllasiewjsaroo9o55ooo"; // 256 bits
        // encryptedString is encrypted form of the string "This is just some test data." It has
        // the initialization vector added as a prefix.
        final String encryptedString = "yDdtrKCl30b+fndIMkhasDhBNk+OGYqiM6uVVF89pu2WSnjMsz1lnw6x4H23QWxP";
        String decryptedString;

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        try {
            decryptedString = doDecryption(encryptedString, SECRET_KEY);
        } catch (Exception e) {
            decryptedString = "Error doing decryption!";
            e.printStackTrace();
        }
        Log.d(TAG, ">>Decrypted string=" + decryptedString);
    }

    /**
     * Decrypt from Base 64 representation of a string with initialization vector prefix.
     *
     * @param sourceBase64 Initialization vector prefixed to string to decrypt in base 64.
     * @param secretKey    The secret key used to do the encryption and the decryption.
     * @return The decrypted string.
     * @throws Exception Exception
     */

    String doDecryption(String sourceBase64, String secretKey) throws Exception {
        Cipher cipher;                  // The cipher used to encrypt and decrypt
        int cipherBlockSize;            // Size of the cipher block
        byte[] sourceBytes;             // Decoded byte array from sourceBase64
        byte[] iv;                      // Initialization vector
        byte[] bytesToDecrypt;          // Bytes on which to perform decryption

        // String passed in is in base 64. Translate so we can work with it.
        sourceBytes = Base64.decode(sourceBase64.getBytes("UTF-8"), Base64.DEFAULT);

        // Get the secretKey spec for our secret key to work with our cipher.
        SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes("UTF-8"), "AES");

        // Set up the cipher.
        cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipherBlockSize = cipher.getBlockSize();

        // The initialization vector prefixes the string that was passed in (sourceBase64).
        // The length of this initialization vector is the same as our cipher's blocksize.
        iv = new byte[cipherBlockSize];

        // Split the inititializatoin vector from the bytes we need to decrypt.
        bytesToDecrypt = new byte[sourceBytes.length - cipherBlockSize];
        System.arraycopy(sourceBytes, 0, iv, 0, iv.length);
        System.arraycopy(sourceBytes, iv.length, bytesToDecrypt, 0, bytesToDecrypt.length);

        // Now do the actual decryption.
        cipher.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(iv));
        return new String(cipher.doFinal(bytesToDecrypt));
    }

    private static final String TAG = "MainActivity";
}
Cheticamp
  • 61,413
  • 10
  • 78
  • 131
  • dont work,return error: javax.crypto.BadPaddingException: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt – David Hackro Apr 16 '17 at 16:30
  • @DavidHackro I think that is progress. Have you tried the code I supplied as is? I just retested it. It does work and does a proper decryption of the encoded text that I supplied. It will not work with the text you supplied since there is just something wrong with that text. The problem is either that your encoded text was somehow corrupted or the wrong decryption is being applied. The error and the lack of a closing quote in the code you supplied suggests that the text may have truncated. Go back and verify that the text was pulled correctly and that you have the right key. – Cheticamp Apr 16 '17 at 16:44
  • @DavidHackro I took another look at the length of your encrypted data and it is, by my calculation, 784 bytes long which is 49 blocks of 16 bytes and that conforms to what is valid for AES. Your key looks to be 128 bits encoded to base64, also valid. Either the key is incorrect or the data is. You may also have the wrong cipher. I am also seeing the error "javax.crypto.BadPaddingException: error:1e000065:Cipher functions:OPENSSL_internal:BAD_DECRYPT". – Cheticamp Apr 16 '17 at 19:17
1

I think the problem it's on this line:

byte[] results = cipher.doFinal(Base64.encode(text.getBytes("UTF-8"), Base64.DEFAULT));

It seems like you're base64 coding something that's already base64 coded. I think you must change it for the next code:

String decoded = new String(cipher.doFinal(Base64Coder.decode(text)), "UTF-8");
ThanatosMK
  • 130
  • 7