AES Interop Between PHP and Java (Part 2)
Monday, March 12th, 2007… Give him a fish; you fed him for today. Teach him how to fish; you fed him for life …
The Problem: In a previous post, I show how to use AES in PHP to encrypt a message and decrypt it in Java. Then Amit asked if it could be done the other way around.
Again, without all the knowledge about AES, Key, CBC, ECB, etc, etc… I will present a simple solution. Keep in mind, these are bits and pieces, so that I wouldn’t take all the fun out of you. I will just show you how to encrypt and decrypt and you can implement other things in between so that you can also have the fun.
The Solution:
- Encrypt a message in Java:
001 import javax.crypto.*; 002 import javax.crypto.spec.*; 003 import java.security.*; 004 import java.io.*; 005 006 public class tester { 007 public static String bytesToHex(byte[] data) { 008 if (data==null) { 009 return null; 010 } else { 011 int len = data.length; 012 String str = ""; 013 for (int i=0; i<len; i++) { 014 if ((data[i]&0xFF)<16) 015 str = str + "0" + java.lang.Integer.toHexString(data[i]&0xFF); 016 else 017 str = str + java.lang.Integer.toHexString(data[i]&0xFF); 018 } 019 return str; 020 } 021 022 public static void main(String[] args) throws Exception { 023 String plaintext = "Hello World "; 024 String key = "01234567890abcde"; 025 String iv = "fedcba9876543210"; 026 027 SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES"); 028 IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes()); 029 030 Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); 031 cipher.init(Cipher.ENCRYPT_MODE,keyspec,ivspec); 032 byte[] encrypted = cipher.doFinal(plaintext.getBytes()); 033 034 System.out.println("Encrypted: " + bytesToHex(encrypted)); 035 036 cipher.init(Cipher.DECRYPT_MODE,keyspec,ivspec); 037 byte[] decrypted = cipher.doFinal(encrypted); 038 System.out.println(new String(decrypted)); 039 } 040 } - The output of the Java program should be “444e6969a269829a3e59a86300614fc5″. Take note that I cheated by making the plain text message as “Hello World ” (16 bytes). You can work out the padding part of Java program (or someone is nice enough to put it in the comment).
- We just take the output and decrypt it over in the following PHP program:
001 <?php 002 function hex2bin($hexdata) { 003 $bindata=""; 004 005 for ($i=0;$i<strlen($hexdata);$i+=2) { 006 $bindata.=chr(hexdec(substr($hexdata,$i,2))); 007 } 008 009 return $bindata; 010 } 011 012 $cipher = "rijndael-128"; 013 $mode = "cbc"; 014 $secret_key = "01234567890abcde"; 015 $iv = "fedcba9876543210"; 016 017 $td = mcrypt_module_open($cipher, "", $mode, $iv); 018 019 mcrypt_generic_init($td, $secret_key, $iv); 020 $decrypted_text = mdecrypt_generic($td, hex2bin("444e6969a269829a3e59a86300614fc5")); 021 echo trim($decrypted_text); 022 mcrypt_generic_deinit($td); 023 mcrypt_module_close($td); 024 ?> - The output should be “Hello World”.