Encryption Crypt – попытка работать на PHP так же, как Perl

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