Я мало что знаю о шифровании, но мне удалось заставить AES работать на PHP ... немного. Вот несколько функций, которые я использую:
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));
}
Они немного изменены из комментария на странице документации PHP для mcrypt . (Я изменил с dev_urandom на rand, так как нахожусь в окне Windows, где dev_urandom недоступен.)
В любом случае ключ, который я использую в этих функциях, определяется следующим образом:
define("PSK", pack("H*", "abcd7b5ca46e12345678a8161fdacee9"));
Я называю свою функцию так:
echo bin2hex(aes_encrypt("wootwootwootwootwootwootwoo", PSK));
Теперь первые 16 байтов (32 цифры) полученной шестнадцатеричной строки в порядке. Следующие 16 байтов не соответствуют ожидаемым.
Видите, я отправляю эти данные на внешний веб-сервис, который затем расшифровывает их. Я (к сожалению) не могу дать один тестовый пример, который у меня есть, не раздавая свой ключ шифрования и данные. Мне ужасно жаль, но я надеюсь, что кто-то, знакомый с mcrypt, сможет взглянуть на это и сказать мне, что я делаю неправильно.
Опять же, извините за отсутствие надежного контрольного примера, но я очень благодарен за любую помощь, которую вы можете оказать!
РЕДАКТИРОВАТЬ: Кажется, мой провайдер, которому я отправляю сообщения, использует нулевой IV. Следуя совету Рука, я переключился в режим CBC и удалил ненужный код, связанный с ключом. Вот мои новые функции:
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);
}