title: How to create javax.crypto.SecretKey based on password and salt
body: <p>I am not a security expert.</p>
  <p>I have a requirement to generate <code>javax.crypto.SecretKey</code> based on <code>password</code> and <code>salt</code>.</p>
  <p>In the existing code, we already have logic to generate <code>javax.crypto.SecretKey</code> but not based on <code>password and </code>salt`.</p>
  <p>Also, in the existing code we already encrypt and decrypt using the <code>javax.crypto.SecretKey</code>.
  There is already lot of data in DB which is encrypted using existing encrypt code and I dont think I can change existing encrypt and decrypt logic.</p>
  <p>I am getting below the error when I try to decrypt data using the key generated based on <code>password</code> and <code>salt</code> with existing decrypt code.</p>
  <pre><code>key.getAlgorithm(): DESede
  encryptedData: [B@31dc339b
  Exception in thread &quot;main&quot; javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
      at com.sun.crypto.provider.CipherCore.unpad(CipherCore.java:975)
      at com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:1056)
      at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:853)
      at com.sun.crypto.provider.DESedeCipher.engineDoFinal(DESedeCipher.java:294)
      at javax.crypto.Cipher.doFinal(Cipher.java:2168)
      at com.arjun.mytest.PMAdminKeyTest.main(PMAdminKeyTest.java:41)
  </code></pre>
  <pre><code>
  import java.security.KeyStore;
  import java.security.Provider;
  import java.security.spec.KeySpec;
  
  import javax.crypto.Cipher;
  import javax.crypto.KeyGenerator;
  import javax.crypto.SecretKey;
  import javax.crypto.SecretKeyFactory;
  import javax.crypto.spec.PBEKeySpec;
  import javax.crypto.spec.SecretKeySpec;
  
  public class PMAdminKeyTest {
  
      public static void main(String[] args) throws Exception {
          // Requirement is to generate Key based on password and salt
          SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(&quot;PBKDF2WithHmacSHA256&quot;);
          KeySpec keySpec = new PBEKeySpec(&quot;password&quot;.toCharArray(), &quot;salt&quot;.getBytes(), 65536, 192);
          SecretKey key = new SecretKeySpec(secretKeyFactory.generateSecret(keySpec).getEncoded(), &quot;DESede&quot;);
  
          System.out.println(&quot;key.getAlgorithm(): &quot; + key.getAlgorithm());
  
          byte[] data = &quot;12345678&quot;.getBytes(&quot;UTF8&quot;);
  
          // Existing encrypt and decrypt code. There is already lot of data in DB
          // encrypted in this manner. I dont think I can change this code.
          Cipher cipher = Cipher.getInstance(key.getAlgorithm() + &quot;/ECB/PKCS5Padding&quot;);
          cipher.init(Cipher.ENCRYPT_MODE, key);
          byte[] encryptedData = cipher.doFinal(data);
  
          System.out.println(&quot;encryptedData: &quot; + encryptedData.toString());
  
          cipher.init(Cipher.DECRYPT_MODE, key);
          byte[] decryptedData = cipher.doFinal(data);
  
          System.out.println(&quot;decryptedData: &quot; + decryptedData.toString());
      }
  
  }
  </code></pre>