PHP AES Расшифровка рабочего шифрования НЕ - PullRequest
3 голосов
/ 18 ноября 2011

Итак, у меня есть 3 части из 4 работающих, iOS Encrypt-Decrypt с этой Link И я могу расшифровать данные, зашифрованные с iOS У меня возникли проблемы с шифрованием на стороне PHP.Когда я делаю эхо-код шифрования.PHP печатает что-то вроде F> HFl8aR, что это значит?

SALTKEY = 'a16byteslongkey!';

Код расшифровки: Работает

     $result =  mcrypt_decrypt(MCRYPT_RIJNDAEL_128, (SALTKEY . str_repeat(chr(0x00), 16)), 
                               base64_decode($text), 'ecb');
     $pad_char = ord(substr($result, -1));
     return substr($result, 0, strlen($result) - $pad_char);

Код шифрования: Не работает

     $result =  mcrypt_encrypt(MCRYPT_RIJNDAEL_128, (SALTKEY . str_repeat(chr(0x00), 16)), 
                               base64_encode($text), 'ecb');
     $pad_char = ord(substr($result, -1));
     return substr($result, 0, strlen($result) - $pad_char);
  • Результаты на iOS : Text = "Hello "
    Encryption =" 7opqbb7sEVNoXplyQv / X8g == "
    Расшифровка (7opqbb7sEVNoXplyQv / X8g ==) =" Hello "

  • Результаты по PHP : Text = "7opqbb7sEVNoXplyQv / X8g =="
    Decryption = "Hello"
    Шифрование (Hello) = "_ ~ TPn ~ p3MF? "

Ответы [ 3 ]

3 голосов
/ 18 ноября 2011

Я думаю, совершенно очевидно, что шифрование IOS дает 7-битный результат (похоже на кодирование base64), в то время как PHP дает 8-битное представление.

Вы, похоже, не поняли, как реверсирует операцию.

Расшифровка выполняется путем base64_decode ввода, затем применения mcrypt_decrypt,Следовательно, чтобы выполнить это в обратном порядке, вам нужно сначала mcrypt_encrypt, а затем , а затем base64_encode.

, т.е.

 $result =  base64_encode(
          mcrypt_encrypt(MCRYPT_RIJNDAEL_128, 
                (SALTKEY . str_repeat(chr(0x00), 16)), 
                $text, 'ecb'));
2 голосов
/ 18 ноября 2011

Ваше шифрование выглядит очень поддельным:

 $result =  mcrypt_encrypt(MCRYPT_RIJNDAEL_128, (SALTKEY . str_repeat(chr(0x00), 16)), 
                           base64_encode($text), 'ecb');
 $pad_char = ord(substr($result, -1));
 return substr($result, 0, strlen($result) - $pad_char);

Вы кодируете текст с помощью base64, затем шифруете его, а затем и затем пытаетесь удалить заполнение?

Вместо этого вы должны

  • добавить заполнение (если функция шифрования еще не делает этого),
  • шифровать
  • затем закодируйте в base-64 результат (если вы хотите, чтобы он каким-то образом читался людьми или передача по небинарно-безопасному каналу).

Это может выглядеть так:

$padded = pad($text);
$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, (SALTKEY . str_repeat(chr(0x00), 16)), 
                       $padded, 'ecb');
$result = base64_encode($encrypted);

(Посмотрите заметки, сделанные пользователем в документации mcrypt_encrypt для примера того, как создать заполнение.)

Конечно, есть еще несколько замечаний:

  • Никогда не используйте режим ECB, если вы ничего не знаете о криптографии. Это небезопасный режим работы. Используйте режим CBC (со случайным вектором инициализации, который отправляется с данными).

  • Вы создаете свой ключ, заполняя SALTKEY нулями. Это делает ваш ключ в действительности слабее, чем необходимо. (Наличие ключа, жестко запрограммированного в коде, в любом случае является плохой идеей.) Предоставьте полный 128-битный ключ или извлеките его из пароля с помощью соли и функции вывода ключа (например, PBKDF-2) с большим количеством итераций.

  • Ваша функция дешифрования должна также проверять правильность заполнения (т. Е. Состоит из идентичных байтов), а не просто удалять его.

  • Вы также должны использовать код аутентификации сообщения (MAC) со своим сообщением, чтобы избежать атак с выбранным шифротекстом, которые позволяют расшифровать сообщение.

1 голос
/ 03 января 2012

см. Мой пост здесь: PHP iOS AES Шифрование

Я продолжаю репостить это, поскольку вижу один и тот же вопрос снова и снова.


Я только что прошел такой же проект. Я использовал библиотеку, на которую вы ссылаетесь в «Также считается ...»

Вот пример кода для расшифровки с помощью php:

$iv2 = '';
for($i=0;$i<16;$i++){
    $iv2 .= "\0";   
}
$plain_text_CBC = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $encrypted_text, MCRYPT_MODE_CBC, $iv2);
var_dump($plain_text_CBC);

Убедитесь, что ваши ключи 256-битные (32 символа, у меня еще не было проблем с кодировкой, но если это так, помните, что вы шифруете байты, а не символы). Обратите внимание, что 128 в MCRYPT_RIJNDAEL_128 - это размер блока, а не размер ключа, тогда как в методе AES256DecryptWithKey 256 - это ссылка на размер ключа, а размер блока - 128. AES256DecryptWithKey работает в режиме CBC, но имеет нулевой вектор инициализации ( IV).

CBC означает, что каждый блок зависит от последнего блока, и поэтому он использует предварительно установленный, обычно случайный, «блок -1», называемый IV

ECB означает, что каждый блок зашифрован одинаковым образом, поэтому он показывает, когда два блока в одном и том же сообщении совпадают. Упомянутая библиотека не использует его, поэтому я упомянул только для контраста.

Использование нулевого iv (0000000000000000 в байтах) считается небезопасным, но оно обеспечивает некоторую дополнительную безопасность (но все же можно будет определить, были ли первые 16 символов вашего простого текста одинаковыми каждый раз ). Чтобы это исправить, вам нужно создать переменную NSData * iv для IV и изменить аргумент CCcrypt NSData + AESCrypt.m, чтобы добавить [iv bytes] для параметра iv (я еще не тестировал этот код), и вы бы нужно сохранить этот iv и передать его php вместе с вашим сообщением. Но сначала я бы проверил, чтобы все работало с нуля. Iv.

...