title: AES Encryption/Decryption : Given final block not properly padded
body: <p>I am trying to write methods to encrypt or decrypt String (which mostly will be numeric). It works fine for some texts(e.g.- '1010000011','1010000012', '1010000013') but gives following error for others(e.g.- '1010000014', '1010000018'):</p>
  
  <blockquote>
    <p>javax.crypto.BadPaddingException: Given final block not properly
    padded</p>
  </blockquote>
  
  <p>Here goes my code:</p>
  
  <pre><code>public static SecretKey secKey;
  private static IvParameterSpec ivspec;
  static {
      try {
          SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
          KeySpec spec = new PBEKeySpec("i15646dont6321wanna".toCharArray(),
                  "ahhalkdjfslk3205jlk3m4ljdfa85l".getBytes("UTF-8"), 65536, 256);
          SecretKey tmp = factory.generateSecret(spec);
          secKey = new SecretKeySpec(tmp.getEncoded(), "AES");
          byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
          ivspec = new IvParameterSpec(iv);
      } catch (NoSuchAlgorithmException | InvalidKeySpecException | UnsupportedEncodingException e) {
          e.printStackTrace();
      }
  }
  
  public static String encryptData(String textToEncrypt) {
  
      byte[] encryptedBytes = null;
      String encryptedText = "";
      try {
          byte[] byteToEncrypt = textToEncrypt.getBytes(Charset.defaultCharset());
          Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
          cipher.init(Cipher.ENCRYPT_MODE, secKey, ivspec);
          encryptedBytes = cipher.doFinal(byteToEncrypt);
          encryptedText = new String(encryptedBytes);
      } catch (NoSuchAlgorithmException | IllegalBlockSizeException | BadPaddingException
              | InvalidKeyException | NoSuchPaddingException | InvalidAlgorithmParameterException e) {
          e.printStackTrace();
      }
      return encryptedText;
  }
  
  public static String decryptData(String textToDecrypt) {
  
      byte[] decryptedBytes = null;
      String decryptedText = "";
      try {
          byte[] byteToDecrypt = textToDecrypt.getBytes(Charset.defaultCharset());
          Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
          cipher.init(Cipher.DECRYPT_MODE, secKey, ivspec);
          decryptedBytes = cipher.doFinal(byteToDecrypt);
          decryptedText = new String(decryptedBytes);
      } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
              | IllegalBlockSizeException | BadPaddingException
              | InvalidAlgorithmParameterException e) {
          e.printStackTrace();
      }
      return decryptedText;
  }
  </code></pre>
  
  <p>The String to be encrypted is read from file and be written to some other file after encryption. This encrypted text will have to be decrypted back later. I am calling these methods in following manner:</p>
  
  <pre><code>String[] lineArray = line.split(" | "); //line is read from a file. 
  String encryptedText = AESEncryption.encryptData(lineArray[0]);
  String decryptedText = AESEncryption.decryptData(encryptedText);
  System.out.println("Original Text: " + lineArray[0] + " | Encrypted text: "
                  + encryptedText + " | Decrypted again: " + decryptedText);
  </code></pre>