title: Encrypt/Decrypt with AES and salt size of 32
body: <p>I have to create a weservice that sends an encrypted String with AES, a salt size of 32 and a given password. I'm trying to make my code work but when I try to decrypt a String that they gave me to check if the decrypting is working I get an error:</p>
  
  <blockquote>
    <p><code>Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded</code> </p>
  </blockquote>
  
  <p>My code is below:</p>
  
  <pre><code>import javax.crypto.*;
  import javax.crypto.spec.*;
  import java.security.*;
  import java.security.spec.InvalidKeySpecException;
  
  /**
   * parts of this code were copied from the StandardPBEByteEncryptor class from the  Jasypt (www.jasypt.org) project
   */
  
  public class AESCrypt {
      //private final String KEY_ALGORITHM = "PBEWITHSHA256AND128BITAES-CBC-BC";
      private final String KEY_ALGORITHM = "PBEWithSHA256And256BitAES-CBC-BC";
      private final String MODE_PADDING = "/CBC/PKCS5Padding";
      private final int DEFAULT_SALT_SIZE_BYTES = 32;
  
      private final SecureRandom rand;
  
      private final String passwd = "8g5qT74KdUY";
  
      public AESCrypt() throws Exception {
      rand = SecureRandom.getInstance("SHA1PRNG");
  }
  
  private byte[] generateSalt(int size) {
      byte[] salt = new byte[size];
      rand.nextBytes(salt);
  
      return salt;
  }
  
  private SecretKey generateKey(String algorithm, int keySize, byte[] salt) throws NoSuchProviderException, NoSuchAlgorithmException, InvalidKeySpecException {
      SecretKeyFactory factory = SecretKeyFactory.getInstance(KEY_ALGORITHM);
      PBEKeySpec pbeKeySpec = new PBEKeySpec(passwd.toCharArray(), salt, 100000);
      SecretKey tmpKey = factory.generateSecret(pbeKeySpec);
      byte[] keyBytes = new byte[keySize / 8];
      System.arraycopy(tmpKey.getEncoded(), 0, keyBytes, 0, keyBytes.length);
  
      return new SecretKeySpec(keyBytes, algorithm);
  }
  
  private byte[] generateIV(Cipher cipher) {
      byte[] iv = new byte[cipher.getBlockSize()];
      rand.nextBytes(iv);
  
      return iv;
  }
  
  private byte[] appendArrays(byte[] firstArray, byte[] secondArray) {
      final byte[] result = new byte[firstArray.length + secondArray.length];
  
      System.arraycopy(firstArray, 0, result, 0, firstArray.length);
      System.arraycopy(secondArray, 0, result, firstArray.length, secondArray.length);
  
          return result;
  }
  
  
  public byte[] encrypt(String algorithm, int keySize, final byte[] message) throws Exception {
      Cipher cipher = Cipher.getInstance(algorithm + MODE_PADDING);
  
      // The salt size for the chosen algorithm is set to be equal
      // to the algorithm's block size (if it is a block algorithm).
      int saltSizeBytes = DEFAULT_SALT_SIZE_BYTES;
      int algorithmBlockSize = cipher.getBlockSize();
      if (algorithmBlockSize &gt; 0) {
          saltSizeBytes = algorithmBlockSize;
      }
  
      // Create salt
      final byte[] salt = generateSalt(saltSizeBytes);
  
      SecretKey key = generateKey(algorithm, keySize, salt);
  
      // create a new IV for each encryption
      final IvParameterSpec ivParamSpec = new IvParameterSpec(generateIV(cipher));
  
      // Perform encryption using the Cipher
      cipher.init(Cipher.ENCRYPT_MODE, key, ivParamSpec);
      byte[] encryptedMessage = cipher.doFinal(message);
  
      // append the IV and salt
      encryptedMessage = appendArrays(ivParamSpec.getIV(), encryptedMessage);
      encryptedMessage = appendArrays(salt, encryptedMessage);
  
      return encryptedMessage;
  }
  
  public byte[] decrypt(String algorithm, int keySize, final byte[] encryptedMessage) throws Exception {
      Cipher cipher = Cipher.getInstance(algorithm + MODE_PADDING);
  
      // determine the salt size for the first layer of encryption
      int saltSizeBytes = DEFAULT_SALT_SIZE_BYTES;
      int algorithmBlockSize = cipher.getBlockSize();
      if (algorithmBlockSize &gt; 0) {
          saltSizeBytes = algorithmBlockSize;
      }
      System.out.println("saltSizeBytes:"+saltSizeBytes);
  
      byte[] decryptedMessage = new byte[encryptedMessage.length];
      System.arraycopy(encryptedMessage, 0, decryptedMessage, 0, encryptedMessage.length);
  
      // extract the salt and IV from the incoming message
      byte[] salt = null;
      byte[] iv = null;
      byte[] encryptedMessageKernel = null;
      final int saltStart = 0;
      final int saltSize = (saltSizeBytes &lt; decryptedMessage.length ? saltSizeBytes : decryptedMessage.length);
      //final int saltSize = 32;
      //System.out.println("saltSize:"+saltSize);
  
      final int ivStart = (saltSizeBytes &lt; decryptedMessage.length ? saltSizeBytes : decryptedMessage.length);
      final int ivSize = cipher.getBlockSize();
      final int encMesKernelStart = (saltSizeBytes + ivSize &lt; decryptedMessage.length ? saltSizeBytes + ivSize : decryptedMessage.length);
      final int encMesKernelSize = (saltSizeBytes + ivSize &lt; decryptedMessage.length ? (decryptedMessage.length - saltSizeBytes - ivSize) : 0);
  
      salt = new byte[saltSize];
      iv = new byte[ivSize];
      System.out.println("saltSize:"+saltSize);
      System.out.println("ivSize:"+ivSize);
  
      encryptedMessageKernel = new byte[encMesKernelSize];
      System.out.println("encryptedMessageKernel");
  
      System.arraycopy(decryptedMessage, saltStart, salt, 0, saltSize);
      System.arraycopy(decryptedMessage, ivStart, iv, 0, ivSize);
      System.arraycopy(decryptedMessage, encMesKernelStart, encryptedMessageKernel, 0, encMesKernelSize);
  
      SecretKey key = generateKey(algorithm, keySize, salt);
      System.out.println("ekey");
  
      IvParameterSpec ivParamSpec = new IvParameterSpec(iv);
  
      // Perform decryption using the Cipher
      cipher.init(Cipher.DECRYPT_MODE, key, ivParamSpec);
      decryptedMessage = cipher.doFinal(encryptedMessageKernel);
  
      // Return the results
      return decryptedMessage;
  }
  </code></pre>
  
  <p>Now I have this information I know it was crypted and I would like to decrypt:</p>
  
  <pre class="lang-none prettyprint-override"><code>Original String: 12334567
   Crypted String: SsH6NO9a64g0U7szvFwSbCkdUF5dNgmxgpt2jU/nFVntG3r2nYxgxLRXri4MW9Z2
         Password: 8g5qT74KdUY
  </code></pre>
  
  <p>When I try to decrypt the <code>SsH...</code> I get the given error. Where is the problem? This is what I do: </p>
  
  <pre><code>String toDecrypt = "SsH6NO9a64g0U7szvFwSbCkdUF5dNgmxgpt2jU/nFVntG3r2nYxgxLRXri4MW9Z2"; 
  byte[] criptata = Base64.decode(toDecrypt); 
  byte[] decriptata = engine.decrypt("AES", 128, criptata);
  String msgdecriptato = new String(decriptata); 
  </code></pre>
  
  <p>This gives me an error.</p>
  
  <p>Here is the code in C# they use to do decrypt:</p>
  
  <pre><code>private const int SaltSize = 32;
  
  /// &lt;summary&gt;
  ///     Decrypts the ciphertext using the Key.
  /// &lt;/summary&gt;
  /// &lt;param name="ciphertext"&gt;The ciphertext to decrypt.&lt;/param&gt;
  /// &lt;param name="key"&gt;The plain text encryption key.&lt;/param&gt;
  /// &lt;returns&gt;The decrypted text.&lt;/returns&gt;
  public  string Decrypt(string ciphertext, string key)
  {
          if (string.IsNullOrEmpty(ciphertext))
              throw new ArgumentNullException("ciphertext");
          if (string.IsNullOrEmpty(key))
              throw new ArgumentNullException("key");
  
          // Extract the salt from our ciphertext
          var allTheBytes = Convert.FromBase64String(ciphertext);
          var saltBytes = allTheBytes.Take(SaltSize).ToArray();
          var ciphertextBytes = allTheBytes.Skip(SaltSize).Take(allTheBytes.Length - SaltSize).ToArray();
  
          using (var keyDerivationFunction = new Rfc2898DeriveBytes(key, saltBytes))
          {
              // Derive the previous IV from the Key and Salt
              var keyBytes = keyDerivationFunction.GetBytes(32);
              var ivBytes = keyDerivationFunction.GetBytes(16);
  
              // Create a decrytor to perform the stream transform.
              // Create the streams used for decryption.
              // The default Cipher Mode is CBC and the Padding is PKCS7 which are both good
              using (var aesManaged = new AesManaged())
              using (var decryptor = aesManaged.CreateDecryptor(keyBytes, ivBytes))
              using (var memoryStream = new MemoryStream(ciphertextBytes))
              using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
              using (var streamReader = new StreamReader(cryptoStream))
              {
                  // Return the decrypted bytes from the decrypting stream.
                  return streamReader.ReadToEnd();
              }
          }
      }
  </code></pre>
  
  <p>Any hint?</p>