Ошибка функции расшифровки PHP
Я пытаюсь отправить данные из моего приложения Android на сервер Apache2, работающий на PHP 5.5, с шифрованием / дешифрованием AES-128 с обеих сторон.
Странно то, что когда я запускаю Java-код в Eclipse для шифрования данных (в качестве теста) и беру зашифрованный результат для расшифровки с помощью PHP на Netbeans, он работает просто отлично. Передача кода на Android также дает те же зашифрованные результаты, но функция дешифрования на сервере не возвращает никаких результатов, она просто дает нулевое значение, я использую тот же код, который я использовал на Netbeans, который работал.
Вот код
if(isset($_POST['param']))
{
$param = $_POST['param'];
$param=decrypt($param, "57238004e784498bbc2f8bf984565090");
}
else
echo "No post Request Received";
function decrypt($encrypted, $key) {
$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, hex2bin($key),hex2bin($encrypted), MCRYPT_MODE_ECB);
echo $decrypted;
$padSize = ord(substr($decrypted, -1));
return substr($decrypted, 0, $padSize*-1);
}
echo $decrypted дает также ноль и возврат.
Пример: шифр: 269B3F5A2208C533AACB51243CFB9CFB Расшифровано до: 28
Кто-нибудь знает, в чем может быть проблема?
1 ответ
После прочтения методов заполнения я больше не могу сомневаться в методе заполнения ввода PKCS5. Тем не менее, метод, используемый для удаления заполнения из выходных данных, все еще оставляет определенную возможность для введения ошибки, с которой вы сталкиваетесь.
Это потому, что 16-байтовая строка заканчивается z
[ ord('z') == 122
] заставит текущий метод сделать substr($data, 0, -122);
который возвращается false
,
Чтобы убедиться, что последние байты заполнены, вам нужно прочитать последний байт, проверить, что последний $padSize
байты в выходных данных являются повторениями этого байта и в этом случае обрезают только строку.
<?php
function decrypt($encrypted, $key) {
$decrypted = mcrypt_decrypt(
MCRYPT_RIJNDAEL_128,
hex2bin($key),
hex2bin($encrypted),
MCRYPT_MODE_ECB);
return unpad($decrypted);
}
function unpad($data) {
$padSize = ord(substr($data, -1));
$padStr = substr($data, strlen($data) - $padSize);
$padCheck = str_pad('', $padSize, chr($padSize));
if( strcmp($padStr, $padCheck) === 0 ) {
return substr($data, 0, $padSize*-1);
} else {
return $data;
}
}
$key = '57238004e784498bbc2f8bf984565090';
$data = '269B3F5A2208C533AACB51243CFB9CFB';
var_dump(decrypt($data, $key));
// Output: string(2) "28"
Кроме того, режим ECB в значительной степени самый слабый, который вы можете выбрать. Посмотрите на изображения в конце раздела ECB в этой статье в Википедии для отличного примера.
Используйте CBC.