I don't know much about encryption, but I was able to get AES working in PHP... somewhat. Here are a couple functions that I am using:
function aes_decrypt($val,$ky)
{
$key="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
for($a=0;$a<strlen($ky);$a++)
$key[$a%16]=chr(ord($key[$a%16]) ^ ord($ky[$a]));
$mode = MCRYPT_MODE_ECB;
$enc = MCRYPT_RIJNDAEL_128;
$dec = @mcrypt_decrypt($enc, $key, $val, $mode, @mcrypt_create_iv( @mcrypt_get_iv_size($enc, $mode), MCRYPT_RAND) );
return rtrim($dec,(( ord(substr($dec,strlen($dec)-1,1))>=0 and ord(substr($dec, strlen($dec)-1,1))<=16)? chr(ord( substr($dec,strlen($dec)-1,1))):null));
}
function aes_encrypt($val,$ky)
{
$key="\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
for($a=0;$a<strlen($ky);$a++)
$key[$a%16]=chr(ord($key[$a%16]) ^ ord($ky[$a]));
$mode=MCRYPT_MODE_ECB;
$enc=MCRYPT_RIJNDAEL_128;
$val=str_pad($val, (16*(floor(strlen($val) / 16)+(strlen($val) % 16==0?2:1))), chr(16-(strlen($val) % 16)));
return mcrypt_encrypt($enc, $key, $val, $mode, mcrypt_create_iv( mcrypt_get_iv_size($enc, $mode), MCRYPT_RAND));
}
These are slightly modified from a comment on the PHP documentation page for mcrypt. (I changed from dev_urandom to rand, as I am on a windows box, where dev_urandom is not available.)
Anyway the key I use in this functions is defined like this:
define("PSK", pack("H*", "abcd7b5ca46e12345678a8161fdacee9"));
I call my function like this:
echo bin2hex(aes_encrypt("wootwootwootwootwootwootwoo", PSK));
Now, the first 16 bytes (32 digits) of the resulting hex string are fine. The next 16 bytes do not match what is expected.
See, I am posting this data to an external webservice that then decrypts it. I (unfortunately) can't give the one test case I have without handing out my encryption key and data. I am terribly sorry about that, but I am hoping someone familiar with mcrypt can look at this and tell me what I am doing wrong.
Again, sorry about the lack of a solid test case, but I am greatly appreciative of any help you can give!
EDIT: It seems my provider that I am posting to is using a null IV. Following Rook's advice, I have switched to CBC mode, and removed the unnecessary code related to the key. Here are my new functions:
function aes_decrypt($val,$key)
{
$mode = MCRYPT_MODE_CBC;
$enc = MCRYPT_RIJNDAEL_128;
$dec = @mcrypt_decrypt($enc, $key, $val, $mode, null);
return rtrim($dec,(( ord(substr($dec,strlen($dec)-1,1))>=0 and ord(substr($dec, strlen($dec)-1,1))<=16)? chr(ord( substr($dec,strlen($dec)-1,1))):null));
}
function aes_encrypt($val,$key)
{
$mode = MCRYPT_MODE_CBC;
$enc=MCRYPT_RIJNDAEL_128;
$val=str_pad($val, (16*(floor(strlen($val) / 16)+(strlen($val) % 16==0?2:1))), chr(16-(strlen($val) % 16)));
return mcrypt_encrypt($enc, $key, $val, $mode, null);
}