AES 128Bit encryption between Java and PHP
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
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");
Cipher cipher;
byte[] encrypted;
cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
encrypted = cipher.doFinal(padString(text).getBytes());
Cipher cipher;
byte[] decrypted;
cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
decrypted = cipher.doFinal(hexToBytes(code));
function encrypt($str, $key) {
$key = $this->hex2bin($key);
$td = mcrypt_module_open("rijndael-128", "", "cbc", "fedcba9876543210");
mcrypt_generic_init($td, $key, CIPHER_IV);
$encrypted = mcrypt_generic($td, $str);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return bin2hex($encrypted);
}
function decrypt($code, $key) {
$key = $this->hex2bin($key);
$code = $this->hex2bin($code);
$td = mcrypt_module_open("rijndael-128", "", "cbc", "fedcba9876543210");
mcrypt_generic_init($td, $key, CIPHER_IV);
$decrypted = mdecrypt_generic($td, $code);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return utf8_encode(trim($decrypted));
}
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;
}
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
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;
}
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
Pausing remoteTimer
This is a simple example on how to create a remoteTimer that can be paused by the user, in this case this is done over a checkbox.
Because the ajax-Helper offers little help in this case, we need the help of javascript. We also have to simulate pausing with start and stop, because the prototype remoteTimer doesn’t offer it.
Javascript
First of all we need a variable to store the timer, in order to be able to stop it later.
var mytimer = null;
Next we need a function to start the timer with the important parameters.
function startTimer(url, update, frequency) {
mytimer = new PeriodicalExecuter(function() {
new Ajax.Updater(update, url , {asynchronous:true, evalScripts:true,
requestHeaders:['X-Update', update]})}, frequency);
}
And for last we need a function to stop the timer.
function stopTimer() {
mytimer.stop();
}
View
Now we can use the javascript-functions in the view.
echo $javascript->codeBlock("startTimer('/yourapp/posts/view', 'mydiv', 5)");
echo $form->checkbox('pause', array('checked' => true,
'onclick' => "if (this.checked){
startTimer('/yourapp/posts/view', 'mydiv', 5);
} else {
stopTimer();
}"));