Расшифровка AESCrypt между iOS и PHP - PullRequest
9 голосов
/ 24 июня 2011

У меня чертовски много времени выясняется, как расшифровать строку, зашифрованную с помощью 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

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

Ответы [ 4 ]

11 голосов
/ 24 июня 2011

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

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

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

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

Преобразование tc. 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 - это схема заполнения, где байт, используемый для заполнения, равен по значению количеству добавленных байтов.В этом примере 11 байтов были добавлены в конец «Hello», превращая ваш 5-байтовый ввод в 16-байтовый блок для AES.11 = 0x0B.

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

$pad_char = ord(substr($result, -1));
$result_without_padding = substr($result, 0, strlen($result) - $pad_char);
2 голосов
/ 24 июня 2011

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

1 голос
/ 24 июня 2011

Во-первых, код 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'
0 голосов
/ 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...