Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

routines:EVP_DecryptFinal_ex:wrong final block length in android

Tags:

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;
}
like image 633
David Hackro Avatar asked Apr 07 '17 00:04

David Hackro


2 Answers

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";
}
like image 180
Cheticamp Avatar answered Sep 21 '22 10:09

Cheticamp


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");
like image 35
ThanatosMK Avatar answered Sep 21 '22 10:09

ThanatosMK