Я написал функции шифрования в Perl, и я пытаюсь работать так же в PHP.
В PERL:
#!/usr/bin/perl use strict; use warnings; use Crypt::CBC; use Crypt::Rijndael; my $cryptkey = '_PRIVATE_'; my $cipher = Crypt::CBC->new( -key => $cryptkey, -salt => 1, -cipher => 'Rijndael', ); my $data = "hello"; my $ciphertext = $cipher->encrypt_hex($data); print "HEX_KEY: '$ciphertext' \n";
Вывод:
HEX_KEY: '53616c7465645f5fc36630f5364619c31ac26e44809c81bf84ae995c22be45ce'
Я пытаюсь работать на PHP и выводить один и тот же HEX, но это не одно и то же, что пошло не так?
class Test { public function Encypt($data, $cryptkey) { $encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $cryptkey, $data, MCRYPT_MODE_CBC); return bin2hex($encrypted); } } $data = "hello"; $test = new Test(); $cryptkey = "_PRIVATE_"; $hex = $test->Encypt($data, $cryptkey); echo $hex;
Вывод
2bab1b8874692176d213e4c23565b304
Crypt::CBC и mcrypt_encrypt используют разные значения по умолчанию, которые приводят к этому несоответствию.
Для mcrypt_encrypt документация предлагает mcrypt_encrypt информацию:
string mcrypt_encrypt ( string $cipher , string $key , string $data , string $mode [, string $iv ] )
$cipher– это имя алгоритма.$key– это ключ шифрования, если он слишком короткий, он будет дополнен байтами NUL.$data– это данные, которые должны быть зашифрованы, если они слишком короткие, они будут дополнены байтами NUL.$mode– режим работы, здесь"cbc"является правильным.$iv– это вектор инициализации, если он не указан, он будет инициализирован как NUL байт.
Для Crypt::CBC мы получаем следующее:
Crypt::CBC->new(KEYWORD_OPTIONS)
-key => STRING– это ключевая фраза, из которой ключ шифрования генерируется некоторыми операциями хэширования.-literal_key => BOOLЕсли установлено, это пропускает хеширование для ключа и использует его как буквенный ключ.-cipher => CIPHER– имя шифра или предварительно инициализированный объект шифрования.-salt => 1 | STRING-salt => 1 | STRINGЕсли установлено значение"1", это приведет к случайной соли. Любые другие значения принимаются как литеральная соль. По умолчанию используется значение-salt => 1если требуется соль. Или что-то в этом роде, документы здесь немного запутывают. Соль не нужна, если установлены оба параметраliteral_keyиliteral_key.-iv => STRING– это вектор инициализации, который обычно генерируется из соли.-header => STRINGконтролирует, какой заголовок добавляется к выходу. По умолчанию используется значение"salt", но также может быть установлено как"none".
Обратите внимание, что RIJNDAEL_128 подразумевает длину ключа 16, тогда как Crypt::CBC предполагает длину ключа 32 .
Использование Crypt::Rijndael без оболочки Crypt::CBC вероятно, предпочтительнее, поскольку это позволяет нам легко установить необходимые параметры для тех же значений по умолчанию, которые использует PHP:
use Crypt::Rijndael; my $key = "_PRIVATE_"; my $data = "hello"; # pad the $key to 16 bytes $key .= "\0" x (16 - length $key); # pad the $data to a multiple of 16 bytes: if (my $distance = length($data) % 16) { $data .= "\0" x (16 - $distance); } my $crypt = Crypt::Rijndael->new($key, Crypt::Rijndael::MODE_CBC); $crypt->set_iv("\0" x 16); my $binary = $crypt->encrypt($data); print unpack("H*", $binary), "\n";
Затем выдает 2bab1b8874692176d213e4c23565b304 .