Расшифровка AESCrypt между iOS и PHP

У меня есть время выяснить, как расшифровать строку, зашифрованную с помощью NSData + AESCrypt.m (поясняется здесь )

Я смотрел на несколько других потоков, но мне нужно только iDevice для отправки строки в файл PHP, зашифрованного, а затем он расшифровывается внутри PHP (где он хранится в базе данных).

Этот код:

NSString *encryptedString = [@"Hello" AES256EncryptWithKey:@"a16byteslongkey!"]; NSLog(@"The strign encrypted : %@",encryptedString); 

Возвращает строку, зашифрованную: 7opqbb7sEVNoXplyQv / X8g ==

И вот мой PHP-код для расшифровки:

 function decrypt_data($data, $key) { return mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key,$data,MCRYPT_MODE_ECB); } function unpadPKCS7($data, $blockSize) { $length = strlen ( $data ); if ($length > 0) { $first = substr ( $data, - 1 ); if (ord ( $first ) <= $blockSize) { for($i = $length - 2; $i > 0; $i --) if (ord ( $data [$i] != $first )) break; return substr ( $data, 0, $i ); } } return $data; } function decrypt_string($string) { $string = unpadPKCS7($string,128); $string = decrypt_data($string,"a16byteslongkey!"); return $string; } die('<br>Basic :'.decrypt_string('7opqbb7sEVNoXplyQv/X8g==')); 

ОБНОВИТЬ:

Выполнял дешифрование MD5 и много экспериментировал, но еще далек от достижения полезных результатов. Это то, что я получил до сих пор:

 Original string : Hello AES256Encrypt result : 7opqbb7sEVNoXplyQv/X8 base64_decode Decrypted: îŠjm¾ìSh^™rBÿ× mcrypt_rijndael_128 : Õ¯Öå«Ž(ás2''u) mcrypt_rijndael_128 & hex2bin : UÃ)ı+úy´e 

К сожалению, независимо от того, как я наклоняюсь и скручиваю это, я просто становлюсь бред. Может ли кто-нибудь увидеть, что я делаю неправильно?

Solutions Collecting From Web of "Расшифровка AESCrypt между iOS и PHP"

Отказ от ответственности: у меня нет опыта разработки iPhone.

Короткий ответ – что тк. сказал. Что-то ужасно неправильно с AES256EncryptWithKey :

Будучи AES256, вы ожидаете, что потребуется 32-байтовый ключ, а не 16-байтовый ключ. Но ОК, скажите, что он укладывает более короткие ключи с нулевыми байтами, чтобы сделать их 32 байтами. Это может объяснить, почему ваш 16-байтовый ключ заполняется 16 символами.

Но когда дело доходит до фактического действия шифрования, оно использует AES 128, но с 32-байтовым ключом. Скажи что?

Преобразование tc.'s Python в PHP:

 $base64encoded_ciphertext = '7opqbb7sEVNoXplyQv/X8g=='; $key = 'a16byteslongkey!'; $padded_key = $key . str_repeat(chr(0x00), 16); // Argh! $result = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $padded_key, base64_decode($base64encoded_ciphertext), 'ecb'); // Yetch - $result ends up being padded with 0x0b's (vertical tab). var_dump(rtrim($result, chr(0x0b))); 

Результат:

string (5) "Hello"

~~

Редактировать: Этот пост от Henno содержит некоторые важные сведения.

~~

Провели некоторые дополнительные исследования. Нулевой пробел на вашем ключе, вероятно, потому, что для AES256 требуется 32-байтовый ключ. Заполнение 0x0B открытым текстом – благодаря PKCS7 . PKCS7 – это схема дополнений, в которой байт, используемый для заполнения, равен по значению количеству добавленных байтов. В этом примере в конец «Hello» добавлено 11 байтов, которые превратили ваш 5-байтовый вход в 16-байтовый блок для AES. 11 = 0x0B.

Таким образом, приведенный выше код не будет работать, если открытый текст не равен length = 5. Вместо этого попробуйте следующее:

 $pad_char = ord(substr($result, -1)); $result_without_padding = substr($result, 0, strlen($result) - $pad_char); 

Зашифрованная строка выглядит так, как будто она закодирована в base64. Попробуйте расшифровать его, прежде чем расшифровать его.

Во-первых, код Objective-C, который вы используете, довольно ужасен:

  • Ключевое пространство сильно ограничено (предположительно байты UTF-8 заканчиваются нулевым байтом, расширенными с нулевыми байтами до 32 байтов). Самый простой способ генерировать случайный ключ – придерживаться ASCII, что ограничивает вас примерно 223,6 бит для размера ключа по умолчанию в 256 бит.
  • Шифрование выполняется в режиме ECB.
  • Кажется, что данные необратимо дополняются 0x0B.

Избегайте его любой ценой. Это не безопасно.

Он может быть «расшифрован» в Python с чем-то вроде этого:

 >>> import Crypto.Cipher.AES >>> import base64 >>> Crypto.Cipher.AES.new('a16byteslongkey!'+'\0'*16).decrypt(base64.b64decode('7opqbb7sEVNoXplyQv/X8g==')) 'Hello\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b' 

см. мой пост здесь: PHP iOS AES Encryption


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

Вот пример кода для расшифровки с помощью 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.