шифрование — 32-символьный ключ PHP AES для mcrypt_encrypt

Рассмотрим следующий код PHP:

<?php
$key = "1234567812345678";
$iv = "1234567812345678";
$data = "Test string";

$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128,
$key,
$data,
MCRYPT_MODE_CBC,
$iv);

print "Encoded1: " . base64_encode($encrypted) . "\n";

$key = "12345678123456781234567812345678";

$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128,
$key,
$data,
MCRYPT_MODE_CBC,
$iv);

print "Encoded2: " . base64_encode($encrypted) . "\n";

При запуске это дает вывод:

Encoded1: iz1qFlQJfs6Ycp+gcc2z4w==
Encoded2: n3D26h/m8CSH0CE+z6okkw==

Обратите внимание, что я украл первый бит кода из PHP Java AES CBC Шифрование Различные результаты

Теперь — вот вопрос:

В первом случае передаваемый ключ представлял собой строку из 16 символов. Если каждый из отдельных символов интерпретируется как 8-битная величина, это дает 128-битный размер ключа, который можно ожидать. Действительно, код Java, который находится на странице StackOverflow, на которую я ссылался выше, делает именно это и получает тот же результат, что и PHP.

Во втором звонке mcrypt_encrypt выше, я удвоил длину ключа. mcrypt_encrypt принимает это с радостью, но выдает другой зашифрованный вывод, чем в первом случае. Поэтому ясно, что он считает это другим ключом — он, например, не берет только первые 128 бит и отбрасывает все прошедшие.

Итак, как же mcrypt_encrypt обработать строку входного ключа, чтобы придумать 128-битный ключ, который MCRYPT_RIJNDAEL_128 алгоритм требует?

Если это имеет какое-то значение, особенно меня интересует случай, когда передается 32-символьная строка, как в моем втором примере — мне нужно создать соответствующую подпрограмму дешифрования (в Java), поэтому мне нужно выяснить, как ключ фактически генерируется в этом случае. На странице, которую я привел, есть очень хороший Java-код (который работает со всеми моими тестовыми примерами) — мне просто не хватает правильного набора ключевых байтов.

3

Решение

Есть два важных параметра для алгоритма Rijndael. Здесь размер ключа (128-бит, 192-бит и 256-бит), а затем есть размер блока (128-битный, 192-битный и 256-битный). 128 в MCRYPT_RIJNDAEL_128 относится к размеру блока. Размер ключа является переменным.

Когда вы передаете ключи различной длины в MCrypt, он автоматически выберет соответствующий размер ключа, поэтому вы не можете и не можете его установить. MCRYPT_RIJNDAEL_128 это AES (AES-128, AES-192, AES-256). MCRYPT_RIJNDAEL_192 а также MCRYPT_RIJNDAEL_256 больше не AES.

Если код Java выдал результат сопоставления для 128-битного ключа, то он также выдаст результат сопоставления для 256-битного ключа.

MCrypt немного странный. До версии PHP 5.6.0 она имела бы любую длину ключа, а не только 128-битную, 192-битную или 256-битную. Ключ будет заполнен 0x00 байтами до следующей допустимой длины ключа.


Поскольку Java не поддерживает ZeroPadding из коробки, вы должны использовать правильную схему заполнения, такую ​​как заполнение PKCS # 5 / PKCS # 7 в PHP. Этот ответ имеет очень хорошую реализацию этого.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]