Я написал функции шифрования в 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
.