title: AES/CBC/PKCS5Padding encrypt in java decrypt in python goes wrong
body: <p>I'm trying to encrypt a data file in a Java and then decrypt in Python.</p>
  
  <p>but the decrypted data file always got some padding bytes remainslike this</p>
  
  <pre><code>my normal content^@^@^@^@^@
  </code></pre>
  
  <p>I actually do the UNPAD action in the python code ( func decrypt_file() )</p>
  
  <p>and when I remove the UNPAD action, I got this:</p>
  
  <pre><code>my normal content^@^@^@^@^@^P^P^P^P^P^P^P^P^P^P^P^P^P^P^P^P
  </code></pre>
  
  <p>SO, It seems that the Java encrypt method did padding TWICE.</p>
  
  <p>I'm so confused and stuck here. Can anybody help? Thanks a lot!</p>
  
  <p>Here is my code.</p>
  
  <p>(1) java version</p>
  
  <pre><code>import java.io.File;
  import javax.crypto.Cipher;
  import javax.crypto.spec.IvParameterSpec;
  import javax.crypto.spec.SecretKeySpec;
  
  public class AESUtil {
      private static final String key = "wesurexZ5!Hcurfit";
      private static final String ivs = "zK2hzBvP%FRJ5%lD";
      public static byte[] encrypt(byte[] strInBytes) throws Exception {
          SecretKeySpec skeySpec = getKey(key);
          Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
          IvParameterSpec iv = new IvParameterSpec(ivs.getBytes("UTF-8"));
          cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
          return cipher.doFinal(strInBytes);
      }
  
      public static byte[] decrypt(byte[] strIn) throws Exception {
          SecretKeySpec skeySpec = getKey(key);
          Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
          IvParameterSpec iv = new IvParameterSpec(ivs.getBytes("UTF-8"));
          cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
          byte[] decrypted = cipher.doFinal(strIn);
          return decrypted;
      }
  
      private static SecretKeySpec getKey(String strKey) throws Exception {
          byte[] arrBTmp = strKey.getBytes();
          byte[] arrB = new byte[16];
          for (int i = 0; i &lt; arrBTmp.length &amp;&amp; i &lt; arrB.length; i++) {
              arrB[i] = arrBTmp[i];
          }
          SecretKeySpec skeySpec = new SecretKeySpec(arrB, "AES");
          return skeySpec;
      }
  }
  </code></pre>
  
  <p>(2) python version</p>
  
  <pre><code>#!/usr/bin/env python
  # -*- coding: utf-8 -*-
  
  import sys
  
  reload(sys)
  sys.setdefaultencoding("utf-8")
  
  from Crypto.Cipher import AES
  
  
  class AESTool(object):
  
      def __init__(self, iv, key):
          self.iv = iv.decode("utf8")
          self.key = key
          bs = AES.block_size
          self.pad = lambda s: s + (bs - len(s) % bs) * chr(bs - len(s) % bs)
          self.unpad = lambda s: s[0:-ord(s[-1])]
  
      def encrypt(self, plain_text):
          try:
              encryptor = AES.new(self.key, AES.MODE_CBC, self.iv)
              encrypted_text = encryptor.encrypt(self.pad(plain_text))
          except Exception as ex:
              raise Exception(ex.message)
  
          return encrypted_text
  
      def decrypt(self, decrypted_text):
          try:
              decryptor = AES.new(self.key, AES.MODE_CBC, self.iv)
              plain_text = decryptor.decrypt(decrypted_text)
          except Exception as ex:
              raise Exception(ex.message)
  
          return self.unpad(plain_text)
  
      def encrypt_file(self, from_full_path, to_full_path, chunksize=64*1024):
          encryptor = AES.new(self.key, AES.MODE_CBC, self.iv)
          try:
              with open(from_full_path, 'rb') as infile:
                  with open(to_full_path, 'wb') as outfile:
                      while True:
                          chunk = infile.read(chunksize)
  
                          if len(chunk) == 0:
                              break
  
                          if len(chunk) &lt; chunksize:
                              outfile.write(encryptor.encrypt(self.pad(chunk)))
                              break
  
                          outfile.write(encryptor.encrypt(chunk))
          except Exception as ex:
              return -1
  
          return 0
  
      def decrypt_file(self, from_full_path, to_full_path, chunksize=64*1024):
          decryptor = AES.new(self.key, AES.MODE_CBC, self.iv)
          try:
              with open(from_full_path, 'rb') as infile:
                  with open(to_full_path, 'wb') as outfile:
                      prev_chunk = None
                      while True:
                          chunk = infile.read(chunksize)
  
                          if len(chunk) == 0 and prev_chunk:
                              outfile.write(self.unpad(decryptor.decrypt(prev_chunk)))
                              break
  
                          if prev_chunk:
                              outfile.write(decryptor.decrypt(prev_chunk))
  
                          if len(chunk) &lt; chunksize:
                              outfile.write(self.unpad(decryptor.decrypt(chunk)))
                              break
  
                          prev_chunk = chunk
          except Exception as ex:
              return -1
  
          return 0
  </code></pre>