title: AES-256-CBC encrypted with PHP and decrypt in Java
body: <p>I am in a situation where a JSON is encrypted in PHP's <code>openssl_encrypt</code> and needs to be decrypted in JAVA.</p>
  
  <pre><code>$encrypted = "...ENCRYPTED DATA...";
  $secretFile = "/path/to/secret/saved/in/text_file";
  $secret = base64_decode(file_get_contents($secretFile));
  var_dump(strlen($secret)); // prints : int(370)
  
  $iv = substr($encrypted, 0, 16);
  $data = substr($encrypted, 16);
  $decrypted = openssl_decrypt($data, "aes-256-cbc", $secret, null, $iv);
  </code></pre>
  
  <p>This <code>$decrypted</code> has correct data which is now decrypted.</p>
  
  <p>Now, the problem is when I try to do same things in Java it doesn't work :(</p>
  
  <pre><code>String path = "/path/to/secret/saved/in/text";
  String payload = "...ENCRYPTED DATA...";
  StringBuilder output = new StringBuilder();
  
  String iv = payload.substring(0, 16);
  byte[] secret = Base64.getDecoder().decode(Files.readAllBytes(Paths.get(path)));
  String data = payload.substring(16);
  
  Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
  SecretKeySpec secretKeySpec = new SecretKeySpec(secret, "AES");
  IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(), 0, cipher.getBlockSize());
  cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); // This line throws exception : 
  
  cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
  </code></pre>
  
  <p>Here it is:</p>
  
  <pre><code>Exception in thread "main" java.security.InvalidKeyException: Invalid AES key length: 370 bytes
  at com.sun.crypto.provider.AESCrypt.init(AESCrypt.java:87)
  at com.sun.crypto.provider.CipherBlockChaining.init(CipherBlockChaining.java:91)
  at com.sun.crypto.provider.CipherCore.init(CipherCore.java:591)
  at com.sun.crypto.provider.AESCipher.engineInit(AESCipher.java:346)
  at javax.crypto.Cipher.init(Cipher.java:1394)
  at javax.crypto.Cipher.init(Cipher.java:1327)
  at com.sample.App.main(App.java:70)
  </code></pre>
  
  <p>I have already visited similar question like</p>
  
  <p><a href="https://stackoverflow.com/questions/42396690/aes-256-cbc-encrypt-in-php-and-decrypt-in-java-or-vice-versa">AES-256 CBC encrypt in php and decrypt in Java or vice-versa</a></p>
  
  <p><a href="https://stackoverflow.com/questions/44259188/openssl-encrypt-256-cbc-raw-data-in-java">openssl_encrypt 256 CBC raw_data in java</a></p>
  
  <p><a href="https://stackoverflow.com/questions/4537099/unable-to-exchange-data-encrypted-with-aes-256-between-java-and-php">Unable to exchange data encrypted with AES-256 between Java and PHP</a></p>
  
  <p>and list continues.... but no luck there</p>
  
  <p>btw, this is how encryption is done in PHP</p>
  
  <pre><code>$secretFile = "/path/to/secret/saved/in/text_file";
  $secret = base64_decode(file_get_contents($secretFile));
  $iv = bin2hex(openssl_random_pseudo_bytes(8));
  $enc = openssl_encrypt($plainText, "aes-256-cbc", $secret, false, $iv);
  return $iv.$enc;
  </code></pre>
  
  <p>and yes, I forgot to mention that my JRE is already at <code>UnlimitedJCEPolicy</code> and I can't change PHP code.</p>
  
  <p>I am totally stuck at this point and can't move forward. Please help out.</p>
  
  <p><strong>EDIT#1</strong></p>
  
  <pre><code>byte[] payload = ....;
  byte[] iv = ....;
  byte[] secret = ....; // Now 370 bits
  byte[] data = Base64.getDecoder().decode(payload);
  
  Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
  SecretKeySpec secretKeySpec = new SecretKeySpec(Arrays.copyOfRange(secret, 0, 32), "AES");
  IvParameterSpec ivParameterSpec = new IvParameterSpec(iv, 0, cipher.getBlockSize());
  
  cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
  byte[] output = cipher.doFinal(data);
  
  System.out.println(new String(output).trim());
  </code></pre>
  
  <p>Above snippet seems to be working with <code>openssl_encrypt</code></p>
  
  <p><strong>EDIT#2</strong></p>
  
  <p>I am not sure if this is correct, but following is what I have done and encryption-decryption on both side are working fine.</p>
  
  <p>Encrypt in PHP, Decrypt in JAVA use <code>AES/CBC/NoPadding</code></p>
  
  <p>Encrypt in JAVA, Decrypt in PHP use <code>AES/CBC/PKCS5Padding</code></p>