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;
    }
    

    RSA encryption between Java and PHP

    Posted in Java by schneimi on November 25, 2008

    This article shows you one way to get RSA encryption working between Java and PHP without any extra libraries or classes, you only need the openssl module activated on PHP side.

    The goal is to encrypt a text with a public key in Java and send the code to PHP where it is decoded with the private key.

    It took me two days and a lot of googling to figure this out, and I hope this will help others not to spend so much time on this topic.

    1) Install and Configure PHP OpenSSL (Windows)

    • php.ini: extension=php_openssl.dll
    • Set environment variable   
      OPENSSL_CONF to C:\Programme\Apache2.2\php\extras\openssl\openssl.cnf
    • Set environment variable   
      PATH to C:\Programme\Apache2.2\php

    2) Generate a private keyfile with PHP

      $keys = openssl_pkey_new();
      $priv = openssl_pkey_get_private($keys);
      openssl_pkey_export_to_file($priv, 'private.pem');
    

    3) Generate a public .der-file from the private keyfile with OpenSSL

    • openssl rsa -in private.pem -pubout -outform DER -out public.der

    4) Import the public key in Java

      File pubKeyFile = new File("public.der");
      DataInputStream dis = new DataInputStream(new FileInputStream(pubKeyFile));
      byte[] keyBytes = new byte[(int) pubKeyFile.length()];
      
      dis.readFully(keyBytes);
      dis.close();
    
      X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
      KeyFactory keyFactory = KeyFactory.getInstance("RSA");
      RSAPublicKey publicKey = (RSAPublicKey)keyFactory.generatePublic(keySpec);
    

    5) Encode the data in Java with the public key

      Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
      cipher.init(Cipher.ENCRYPT_MODE, publicKey);
      encrypted = cipher.doFinal(text.getBytes());
    

    6) Decode the data with the private key in PHP

    $fp = fopen(“private.pem”, “r”);
    $privateKey = fread($fp, 8192);
    fclose($fp);

    $res = openssl_get_privatekey($privateKey);
    openssl_private_decrypt($this->hex2bin($params[‘cipher’]), $decrypted, $res);

    // $decrypted is the result

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

    for ($i = 0; $i < strlen($hexdata); $i += 2) { $bindata .= chr(hexdec(substr($hexdata, $i, 2))); } return $bindata; } [/sourcecode] 7) If you want to decrypt with the public key in PHP as well, you can generate a public.pem file with OpenSSL

    • openssl rsa -in private.pem -out public.pem -outform PEM -puboutr