title: Encrypt and Decrypt by AES algorithm in both python and android
body: <p>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?</p>
  
  <p>Python code :</p>
  
  <pre class="lang-py prettyprint-override"><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:])]
  </code></pre>
  
  <p>Android Code:</p>
  
  <pre class="lang-java prettyprint-override"><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;
  
  }
  
  
  }
  </code></pre>
  
  <p>When I ran this code on android:</p>
  
  <pre><code>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);
  </code></pre>
  
  <p>Then I got this answer:</p>
  
  <pre><code>step1: this is local test
  step2: a0F8MhzkSpRlM+aM1MKzUdVCoXIE5y5hh4PRuwPfAhofKwLJjTUbBvmJzTsKJDqF
  step3: dGhpcyBpcyBsb2NhbCB0ZXN0
  </code></pre>
  
  <p>Do anyone have idea why it happens ?</p>