Schneimi’s Dev Weblog


AES 128Bit encryption between Java and PHP

Posted in Java by schneimi on November 25, 2008

Here is how AES encryption works between Java and PHP using the mcrypt module in PHP.

This is mainly a quick summary of the 4-part tutorial at: http://propaso.com/blog/?cat=6

  • Generate Key in Java
  • String iv = "fedcba9876543210";
    IvParameterSpec ivspec;
    KeyGenerator keygen;
    Key key;
    
    ivspec = new IvParameterSpec(iv.getBytes());
    
    keygen = KeyGenerator.getInstance("AES");
    keygen.init(128);
    key = keygen.generateKey();
    
    keyspec = new SecretKeySpec(key.getEncoded(), "AES");
    
  • Encryption in Java
  • Cipher cipher;
    byte[] encrypted;
    
    cipher = Cipher.getInstance("AES/CBC/NoPadding");
    cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
    encrypted = cipher.doFinal(padString(text).getBytes());
    
  • Decryption in Java
  • Cipher cipher;
    byte[] decrypted;
    
    cipher = Cipher.getInstance("AES/CBC/NoPadding");
    cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
    decrypted = cipher.doFinal(hexToBytes(code));
    
  • Encryption in PHP
  • function encrypt($str, $key) {
      $key = $this->hex2bin($key);    
    
      $td = mcrypt_module_open("rijndael-128", "", "cbc", "fedcba9876543210");
    
      mcrypt_generic_init($td, $key, "fedcba9876543210");
      $encrypted = mcrypt_generic($td, $str);
    
      mcrypt_generic_deinit($td);
      mcrypt_module_close($td);
    
      return bin2hex($encrypted);
    }
    
  • Decryption in PHP
  • function decrypt($code, $key) {
      $key = $this->hex2bin($key);
      $code = $this->hex2bin($code);
    
      $td = mcrypt_module_open("rijndael-128", "", "cbc", "");
    
      mcrypt_generic_init($td, $key, "fedcba9876543210");
      $decrypted = mdecrypt_generic($td, $code);
    
      mcrypt_generic_deinit($td);
      mcrypt_module_close($td);
    
      return utf8_encode(trim($decrypted));
    }
    
  • Additional functions in Java
  • private byte[] hexToBytes(String hex) {
      String HEXINDEX = "0123456789abcdef";
      int l = hex.length() / 2;
      byte data[] = new byte[l];
      int j = 0;
    
      for (int i = 0; i < l; i++) {
        char c = hex.charAt(j++);
        int n, b;
    
        n = HEXINDEX.indexOf(c);
        b = (n & 0xf) << 4;
        c = hex.charAt(j++);
        n = HEXINDEX.indexOf(c);
        b += (n & 0xf);
        data[i] = (byte) b;
      }
    
      return data;
    }
    
    private String padString(String source) {
      char paddingChar = ' ';
      int size = 16;
      int padLength = size - source.length() % size;
    
      for (int i = 0; i < padLength; i++) {
        source += paddingChar;
      }
    
      return source;
    }
    
  • Additional functions in PHP
  • function hex2bin($hexdata) {
      $bindata = "";
    
      for ($i = 0; $i < strlen($hexdata); $i += 2) {
        $bindata .= chr(hexdec(substr($hexdata, $i, 2)));
      }
    
      return $bindata;
    }
    
    About these ads

    20 Responses to 'AES 128Bit encryption between Java and PHP'

    Subscribe to comments with RSS or TrackBack to 'AES 128Bit encryption between Java and PHP'.

    1. Adrian said,

      at my PHP application i need to use code :
      $td = mcrypt_module_open(“rijndael-128″, “”, “cbc”, “”);
      mcrypt_generic_init($td, $key, “fedcba9876543210″);

      cheers ;)

    2. Sebastien said,

      Would it be possible to get the classes since the tutorial is no longer available.

      Do you have something more recent?

      Thanks

    3. efendi said,

      there is no same value if i encrypt to php and decrypt to java, with this value. can u me a clue please:D
      thanks

      • schneimi said,

        What is the difference between the two values? Maybe it’s the same value just differently output.

    4. efendi said,

      I have Try To Encrypt and decrpt the 16 bit char : the char was :
      “Hallo, This is just an example Testing P*[‘#’] (\”:;\”) ~` أفضل 使用 言う
      Selamat 0000 Datang null null @^@ 罚款 غرامة hahahaha baik kok штраф 0001
      Bisa &$+= | ?/ !{haha} 000 0″
      but in the end the java always error or get the allitle different value with php (may be this is because the null padding in php).
      would you give the some clue?
      thanks in advance.

    5. schneimi said,

      I have no obvious clue, but here is a similar problem between java and c++. I just had a quick look through it, maybe that helps.

      http://objectmix.com/java/77240-aes-encrypted-packets-not-same-between-my-java-application-my-c-application.html

    6. efendi said,

      ohh thanks for your help, but may be this helps.
      i tried to changes littel your function:
      private String padString(String source) {
      char paddingChar = ‘ ‘;
      int size = 16;
      int padLength = size – (source.getBytes().length % size);
      if(padLength != 16){
      for (int i = 0; i < padLength; i++) {
      source += paddingChar;
      }
      }
      return source;
      }

      hope this useful for others. thank


    7. […] found this AES 128Bit encryption between Java and PHP Schneimi’s Dev Weblog Then i wonder, where is the key for encryption in java? anyone can […]


    8. […] http://schneimi.wordpress.com/2008/11/25/aes-128bit-encryption-between-java-and-php โดยมีการดัดแปลงเล็กน้อย […]

    9. manhdung said,

      i’m try encrypt with java , content = “this is content test”, return encrypt= ” 6HcuTiBMsA0w%2B8D3koIAGBwYZnCVXbboZ5bLPrXjoto%3D “,but when use php decrypt then result = ” #Â¥!ĦƒÕ‡aÃŽ „€fªµøƒg¾Ö‰#zJín “.hix, i don’t know what happenning. i was copy all code above. please help me. thanks all.

    10. manhdung said,

      here is code:
      php:
      hex2bin($key);
      $code = $this->hex2bin($code);

      $td = mcrypt_module_open(“rijndael-128″, “”, “cbc”, “”);

      mcrypt_generic_init($td, $key, “fedcba9876543210″);
      $decrypted = mdecrypt_generic($td, $code);

      mcrypt_generic_deinit($td);
      mcrypt_module_close($td);

      return utf8_encode(trim($decrypted));
      //return trim($decrypted);
      }
      function encrypt($str, $key) {
      $key = $this->hex2bin($key);

      $td = mcrypt_module_open(“rijndael-128″, “”, “cbc”, “”);

      mcrypt_generic_init($td, $key, “fedcba9876543210″);
      $encrypted = mcrypt_generic($td, $str);

      mcrypt_generic_deinit($td);
      mcrypt_module_close($td);

      return bin2hex($encrypted);
      }

      function hex2bin($hexdata) {
      $bindata = “”;

      for ($i = 0; $i < strlen($hexdata); $i += 2) {
      $bindata .= chr(hexdec(substr($hexdata, $i, 2)));
      }

      return $bindata;
      }

      }
      java:

      package inet.aes.php.java;

      import java.io.IOException;
      import java.net.URLEncoder;
      import java.security.InvalidAlgorithmParameterException;
      import java.security.InvalidKeyException;
      import java.security.Key;
      import java.security.NoSuchAlgorithmException;

      import javax.crypto.BadPaddingException;
      import javax.crypto.Cipher;
      import javax.crypto.IllegalBlockSizeException;
      import javax.crypto.KeyGenerator;
      import javax.crypto.NoSuchPaddingException;
      import javax.crypto.spec.IvParameterSpec;
      import javax.crypto.spec.SecretKeySpec;

      import sun.misc.BASE64Decoder;
      import sun.misc.BASE64Encoder;

      public class AESjava {

      //static Key key;
      public void generate() throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, IOException{
      String iv = "fedcba9876543210";
      IvParameterSpec ivspec;
      KeyGenerator keygen;
      ivspec = new IvParameterSpec(iv.getBytes());

      keygen = KeyGenerator.getInstance("AES");
      keygen.init(128);
      //key = keygen.generateKey();
      //SecretKeySpec keyspec = new SecretKeySpec(key.getEncoded(), "AES");
      SecretKeySpec keyspec = new SecretKeySpec("L7ucmQIe6%2Fnu44".getBytes(), "AES");
      //encrypt
      String result = "";
      BASE64Encoder base64encoder;
      base64encoder = new BASE64Encoder();
      Cipher cipher;
      byte[] encrypted;

      cipher = Cipher.getInstance("AES/CBC/NoPadding");
      cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
      encrypted = cipher.doFinal(padString("this is content test").getBytes());
      result = URLEncoder.encode(base64encoder.encode(encrypted), "UTF-8");

      System.out.println(result+" = encrypted");

      //decrypt
      /*
      * byte[] decrypted;

      cipher = Cipher.getInstance("AES/CBC/NoPadding");
      cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
      decrypted = cipher.doFinal(base64decoder.decodeBuffer(encrypted.toString()));
      * */
      }

      private byte[] hexToBytes(String hex) {
      String HEXINDEX = "0123456789abcdef";
      int l = hex.length() / 2;
      byte data[] = new byte[l];
      int j = 0;

      for (int i = 0; i < l; i++) {
      char c = hex.charAt(j++);
      int n, b;

      n = HEXINDEX.indexOf(c);
      b = (n & 0xf) << 4;
      c = hex.charAt(j++);
      n = HEXINDEX.indexOf(c);
      b += (n & 0xf);
      data[i] = (byte) b;
      }

      return data;
      }

      private String padString(String source) {
      char paddingChar = ' ';
      int size = 16;
      int padLength = size – (source.getBytes().length % size);
      if(padLength != 16){
      for (int i = 0; i < padLength; i++) {
      source += paddingChar;
      }
      }
      return source;
      }

      public static void main(String arg[]) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, IOException{
      AESjava aesJ = new AESjava();
      aesJ.generate();
      }
      }

      file test:

      decrypt(“6HcuTiBMsA0w%2B8D3koIAGBwYZnCVXbboZ5bLPrXjoto%3D”, “L7ucmQIe6%2Fnu44″).” = decode”;

      //echo StringTool::generateRandomString(10).” = random String”;
      ?>

      • schneimi said,

        Hi, as far as I can see, your input parameters are not passed in their hexadecimal representation, but at least the code passes a hex2bin conversion.

    11. Alex said,

      This doesn’t work with UNICODE characters

      • schneimi said,

        Not sure what the problem is, this works for me with UTF-8 characters.

        This is what I do with my string before encryption:

        myUtf8String = new String(myString.getBytes("UTF-8"));
        

        Maybe this helps.

    12. Martin said,

      The PHP parts are wrong, any chance you could update?

      The mcrypt_module_open() function is defined thus:
      resource mcrypt_module_open ( string $algorithm , string $algorithm_directory , string $mode , string $mode_directory )

      but you seem to be passing the IV(?) in as the 4th parameter:
      $td = mcrypt_module_open(“rijndael-128″, “”, “cbc”, “fedcba9876543210″);

      And in the call to mcrypt_generic_init(), defined as int mcrypt_generic_init ( resource $td , string $key , string $iv ), where you need to pass the IV in you are passing an undefined constant instead:

      mcrypt_generic_init($td, $key, CIPHER_IV);

    13. jayadianto said,

      thanks, solved my problem, but i need :
      $td = mcrypt_module_open(“rijndael-128″, “”, “cbc”, “”);
      mcrypt_generic_init($td, $key, “fedcba9876543210″);

      in php application, like post of Adrian . :D

      • schneimi said,

        Thx for the details. I fixed it.

    14. arronwall said,

      Thanks for your sharing.It is appreciated very much. And I wonder whether there are some differences between the java code 128 barcode generation add-in I am testing these days and the one you mentioned above? Do you have any ideas about it? Or any good suggestion? Thanks in advance.


    Leave a Reply

    Fill in your details below or click an icon to log in:

    WordPress.com Logo

    You are commenting using your WordPress.com account. Log Out / Change )

    Twitter picture

    You are commenting using your Twitter account. Log Out / Change )

    Facebook photo

    You are commenting using your Facebook account. Log Out / Change )

    Google+ photo

    You are commenting using your Google+ account. Log Out / Change )

    Connecting to %s


    Follow

    Get every new post delivered to your Inbox.

    %d bloggers like this: