7

I have python and android code for AES encryption. When I encrypt a text in android, it decrypt on python successfully but it can’t decrypt in android side. Do anyone have an idea?

Python code :

import base64
import hashlib
from Crypto import Random
from Crypto.Cipher import AES


class AESCipher:

    def __init__(self, key):
        self.bs = 16
        self.key = hashlib.sha256(key.encode()).digest()

    def encrypt(self, message):
        message = self._pad(message)
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return base64.b64encode(iv + cipher.encrypt(message)).decode('utf-8')

    def decrypt(self, enc):
        enc = base64.b64decode(enc)
        iv = enc[:AES.block_size]
        cipher = AES.new(self.key, AES.MODE_CBC, iv)
        return self._unpad(cipher.decrypt(enc[AES.block_size:])).decode('utf-8')

    def _pad(self, s):
        return s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs)

    @staticmethod
    def _unpad(s):
        return s[:-ord(s[len(s)-1:])]

Android Code:

import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;

import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Arrays;

import android.annotation.SuppressLint;
import android.location.Criteria;
import android.util.Base64;
import android.util.Log;

@SuppressLint("NewApi")
public class Crypt {

private static final String tag = Crypt.class.getSimpleName();

private static final String characterEncoding = "UTF-8";
private static final String cipherTransformation = "AES/CBC/PKCS5Padding";
private static final String aesEncryptionAlgorithm = "AES";
private static final String key = "this is my key";
private static byte[] ivBytes = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
private static byte[] keyBytes;

private static Crypt instance = null;


Crypt()
{
    SecureRandom random = new SecureRandom();
    Crypt.ivBytes = new byte[16];
    random.nextBytes(Crypt.ivBytes); 
}

public static Crypt getInstance() {
    if(instance == null){
        instance = new Crypt();
    }

    return instance;
}

public String encrypt_string(final String plain) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, IOException
{
    return Base64.encodeToString(encrypt(plain.getBytes()), Base64.DEFAULT);
}

public String decrypt_string(final String plain) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, ClassNotFoundException, IOException
{
    byte[] encryptedBytes = decrypt(Base64.decode(plain, 0));
    return Base64.encodeToString( encryptedBytes, Base64.DEFAULT);
}



public   byte[] encrypt(   byte[] mes)
        throws NoSuchAlgorithmException,
        NoSuchPaddingException,
        InvalidKeyException,
        InvalidAlgorithmParameterException,
        IllegalBlockSizeException,
        BadPaddingException, IOException {

    keyBytes = key.getBytes("UTF-8");
    Log.d(tag,"Long KEY: "+keyBytes.length);
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    md.update(keyBytes);
    keyBytes = md.digest();

    Log.d(tag,"Long KEY: "+keyBytes.length);

    AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivBytes);
    SecretKeySpec newKey = new SecretKeySpec(keyBytes, aesEncryptionAlgorithm);
    Cipher cipher = null;
    cipher = Cipher.getInstance(cipherTransformation);

    SecureRandom random = new SecureRandom();   
    Crypt.ivBytes = new byte[16];               
    random.nextBytes(Crypt.ivBytes);            

    cipher.init(Cipher.ENCRYPT_MODE, newKey, random);
//    cipher.init(Cipher.ENCRYPT_MODE, newKey, ivSpec);
    byte[] destination = new byte[ivBytes.length + mes.length];
    System.arraycopy(ivBytes, 0, destination, 0, ivBytes.length);
    System.arraycopy(mes, 0, destination, ivBytes.length, mes.length);
    return  cipher.doFinal(destination);

}

public   byte[] decrypt(   byte[] bytes)
        throws NoSuchAlgorithmException,
        NoSuchPaddingException,
        InvalidKeyException,
        InvalidAlgorithmParameterException,
        IllegalBlockSizeException,
        BadPaddingException, IOException, ClassNotFoundException {

    keyBytes = key.getBytes("UTF-8");
    Log.d(tag,"Long KEY: "+keyBytes.length);
    MessageDigest md = MessageDigest.getInstance("SHA-256");
    md.update(keyBytes);
    keyBytes = md.digest();
    Log.d(tag,"Long KEY: "+keyBytes.length);

    byte[] ivB = Arrays.copyOfRange(bytes,0,16);
    Log.d(tag, "IV: "+new String(ivB));
    byte[] codB = Arrays.copyOfRange(bytes,16,bytes.length);


    AlgorithmParameterSpec ivSpec = new IvParameterSpec(ivB);
    SecretKeySpec newKey = new SecretKeySpec(keyBytes, aesEncryptionAlgorithm);
    Cipher cipher = Cipher.getInstance(cipherTransformation);
    cipher.init(Cipher.DECRYPT_MODE, newKey, ivSpec);
    byte[] res = cipher.doFinal(codB); 
    return  res;

}


}

When I ran this code on android:

String str = "this is local test";
Log.i("myTag", "step1: " + str);
String a = aesCrypt.encrypt_string(str);
Log.i("myTag", "step2: " + a);
String b = aesCrypt.decrypt_string(a);
Log.i("myTag", "step3: " + b);

Then I got this answer:

step1: this is local test
step2: a0F8MhzkSpRlM+aM1MKzUdVCoXIE5y5hh4PRuwPfAhofKwLJjTUbBvmJzTsKJDqF
step3: dGhpcyBpcyBsb2NhbCB0ZXN0

Do anyone have idea why it happens ?

2
  • I am using the above Python code , when i encrypt the String in Android , i am not able to decrypt it in Python (V3.5.2) & vice versa. Commented Dec 26, 2016 at 11:02
  • @Janmejoy. please change code base on following answer of "Artjom B" . I did in python 3.4 and it still works fine. see my comment on answer too Commented Dec 27, 2016 at 10:31

1 Answer 1

5

You're encoding the output after decryption.

public String decrypt_string(final String plain) throws ...
{
    byte[] encryptedBytes = decrypt(Base64.decode(plain, 0));
    return Base64.encodeToString( encryptedBytes, Base64.DEFAULT);
    //     ^--------------------| this 
}

If you only encrypt printable data then you can safely remove the Base64.encodeToString call from the above code. To return the correct type, you can do

return new String(encryptedBytes);
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much. you're right . I changed last line to { return new String(encryptedBytes); } . and it s works perfect. Sometimes we need a few rest after a long time programming ;)
Yes, it happens. I added your suggestion to my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.