Search code examples
androidencryptionaes

AES Encryption of api string response returning extra characters at start


I am trying to decrypt API encrypted response. But the decryption process returning extra characters at the start and also missing a double-quoted characters of JSON format response key shown below:

private void setListener() {

        btnDecode.setOnClickListener (new View.OnClickListener () {
            @Override
            public void onClick(View v) {
              decodeCode();
            }
        });

    }

private void decodeCode() {

        String response = "bk/qo1fYH3aKseRNcXq6FLn2ScpSTZDyse4YINiQV34XTb2mOV95sB8uBemWl9p6XSGVYga+K6/n3LyJEgiyAmijL+y/ahb1h0ehv1Ejej+uVWN4yXWUr4TOFz+78iU5A9+znSQXIQIo8ti9Z+ALpvu4lqrDo2hZbF0OKDxxgOjLF28NSrNpVo9eThaH33vFmYZUZ1zFj281g8ahj6wf0MuL0Ev9bsI9AhX4eW0rJZSacW2/xZH81EPxcojerCzGnALxVGlE/MzxLSieUMWRkxKxQZ/Ux6EhiJy6kTkS4iku1Uk/qQJglj22eiIPROpNARts2lOo09PdsgJZb3DKm+j16FKfEC+fpLykXqQ5shtcW/tB0Qer+XFNBHGblDMYBaVzqahunvzHQKaSu2vF+A==";
        try {
         String responseResult =  encryptUtils.decrypt (response, "1234567891123456");
         txtDecode.setText (responseResult);
        } catch (GeneralSecurityException e) {
            e.printStackTrace ();
        } catch (IOException e) {
            e.printStackTrace ();
        }
}

Here in return I am getting some extra characters before actual string. Also the Response key in which the complete response exist has invalid syntax i.e Response key start double-quote is missing. Decrypted string getting is:

J`@TBBKE@FQResponse":"{\"access_token\":\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6IllhYm5lciIsIm5iZiI6MTU3MjUxNDI2MywiZXhwIjoxNTcyNTE2MDYzLCJpYXQiOjE1NzI1MTQyNjN9.w4cQcr4pT3hyGPW5MOS7QbWL64nvHBf97OJ8DQWDRRg\",\"badge_Id\":\"108817\"}","ResponseMessage":"Login Success"}

And this is my EncryptUtils class. In this I have tried NoPadding encryption also in decrypt method but didn't work for me:

public class EncryptUtils {

    public String encrypt(String value, String key)
            throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException
    {
        byte[] value_bytes = value.getBytes("UTF-8");
        byte[] key_bytes = getKeyBytes(key);
        return Base64.encodeToString(encrypt(value_bytes, key_bytes, key_bytes), 0);
    }

    public byte[] encrypt(byte[] paramArrayOfByte1, byte[] paramArrayOfByte2, byte[] paramArrayOfByte3)
            throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException
    {
        // setup AES cipher in CBC mode with PKCS #5 padding
        Cipher localCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

        // encrypt
        localCipher.init(1, new SecretKeySpec (paramArrayOfByte2, "AES"), new IvParameterSpec (paramArrayOfByte3));
        return localCipher.doFinal(paramArrayOfByte1);
    }

    public String decrypt(String value, String key)
            throws GeneralSecurityException, IOException
    {
        byte[] value_bytes = Base64.decode(value, 0);
        byte[] key_bytes = getKeyBytes(key);
        return new String(decrypt(value_bytes, key_bytes, key_bytes), "UTF-8");
    }

    public byte[] decrypt(byte[] ArrayOfByte1, byte[] ArrayOfByte2, byte[] ArrayOfByte3)
            throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException
    {
        // setup AES cipher in CBC mode with PKCS #5 padding
        Cipher localCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

        // decrypt
        localCipher.init(2, new SecretKeySpec(ArrayOfByte2, "AES"), new IvParameterSpec(ArrayOfByte3));
        return localCipher.doFinal(ArrayOfByte1);
    }

    private byte[] getKeyBytes(String paramString)
            throws UnsupportedEncodingException
    {
        byte[] arrayOfByte1 = new byte[16];
        byte[] arrayOfByte2 = paramString.getBytes("UTF-8");
        System.arraycopy(arrayOfByte2, 0, arrayOfByte1, 0, Math.min(arrayOfByte2.length, arrayOfByte1.length));
        return arrayOfByte1;
    }
}

Solution

  • Your assumption that the IV is a copy of the key appears to be incorrect. It appears that the IV is all zeros. You can confirm this by replacing this line in decrypt:

    return new String(decrypt(value_bytes, key_bytes, key_bytes), "UTF-8");
    

    with

    return new String(decrypt(value_bytes, key_bytes, new byte[16]), "UTF-8");
    

    The decryption result becomes
    {"Status":true,"Response":"{\"access_token\":\"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1bmlxdWVfbmFtZSI6IllhYm5lciIsIm5iZiI6MTU3MjUxNDI2MywiZXhwIjoxNTcyNTE2MDYzLCJpYXQiOjE1NzI1MTQyNjN9.w4cQcr4pT3hyGPW5MOS7QbWL64nvHBf97OJ8DQWDRRg\",\"badge_Id\":\"108817\"}","ResponseMessage":"Login Success"}