title: Cache user password using AES -- BadPaddingException
body: <p>I want a secure solution for caching a user's password on their PC during their session.</p>
  
  <p>I have trawled numerous AES examples and know that this has been answered elsewhere but I must say it is a little confusing. My <strong>aesSecretKey</strong> or <strong>aesInitialisationVector</strong> are not working in the decryption correctly but not sure where the issue lies.</p>
  
  <p>Decrypting results in a <strong>javax.crypto.BadPaddingException: Given final block not properly padded</strong> exception.</p>
  
  <p>My class looks like this</p>
  
  <pre><code>public class LockManagerTest {
      // Need to share the IV and key between encode and decode
      private static byte[] aesInitialisationVector;
      private static SecretKey aesSecretKey;
      private static Cipher aesCipher;
  
      public LockManagerTest(String sessionKey) {
          try {
              byte[] key = getSecretKey(sessionKey.toCharArray(), getSalt(32),
                                        65536, 128);
              aesSecretKey = new SecretKeySpec(key, "AES");
              aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
              aesCipher.init(Cipher.ENCRYPT_MODE, aesSecretKey);
              AlgorithmParameters params = aesCipher.getParameters();
              aesInitialisationVector =
                      params.getParameterSpec(IvParameterSpec.class).getIV();
          } catch (Exception e) {
              Util.handleException(e);
          }
      }
  
      private static byte[] getSecretKey(char[] plaintext,
                                         byte[] salt,
                                         int iterations,
                                         int keySize)
              throws Exception {
          PBEKeySpec spec = new PBEKeySpec(plaintext, salt, iterations, keySize);
          SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
          return skf.generateSecret(spec).getEncoded();
      }
  
      private static byte[] getSalt(int keyLength) throws Exception {
          SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
          byte[] salt = new byte[keyLength];
          random.nextBytes(salt);
          return salt;
      }
  
      public byte[] encryptedAes(char[] input) throws Exception {
          // WRONG
          // aesCipher.init(Cipher.ENCRYPT_MODE, aesSecretKey);
          //
          aesCipher.init(Cipher.ENCRYPT_MODE, aesSecretKey, 
                         new IvParameterSpec(aesInitialisationVector);
          CharBuffer cBuf = CharBuffer.wrap(input);
          byte[] normalised = Charset.forName("UTF-8").encode(cBuf).array();
          byte[] ciphertext = aesCipher.doFinal(normalised);
          return ciphertext;
      }
  
      public byte[] decryptAes(byte[] ciphertext) throws Exception {
          aesCipher.init(Cipher.DECRYPT_MODE,
                  aesSecretKey, new IvParameterSpec(aesInitialisationVector));
          byte[] plaintext = aesCipher.doFinal(ciphertext);
          return plaintext;
      }
  }
  </code></pre>
  
  <p>Comments regarding the level of security appreciated also.</p>