Crypt::CBC
and mcrypt_encrypt
使用不同的默认值,这会导致这种不匹配。
For mcrypt_encrypt http://www.php.net/manual/en/function.mcrypt-encrypt.php,文档提供了以下信息:
string mcrypt_encrypt ( string $cipher , string $key , string $data , string $mode [, string $iv ] )
-
$cipher
是算法名称。
-
$key
是加密密钥,如果太短,将用 NUL 字节填充。
-
$data
是要加密的数据,如果太短就会用NUL字节填充。
-
$mode
是操作模式,这里"cbc"
是正确的。
-
$iv
是初始化向量,如果没有提供,它将被初始化为 NUL 字节。
For Crypt::CBC https://metacpan.org/pod/Crypt%3a%3aCBC,我们得到这样的行为:
Crypt::CBC->new(KEYWORD_OPTIONS)
-
-key => STRING
是通过一些哈希操作生成加密密钥的密码。
-
-literal_key => BOOL
如果设置,这将跳过哈希-key
并将其用作文字键。
-
-cipher => CIPHER
密码的名称或预初始化的密码对象。
-
-salt => 1 | STRING
如果设置为"1"
,这将产生随机盐。任何其他值都被视为字面盐。这默认为-salt => 1
如果需要盐。或者类似的东西,这里的文档有点混乱。如果两者都满足,则不需要盐-iv
and literal_key
选项已设置。
-
-iv => STRING
是初始化向量,通常由盐生成。
-
-header => STRING
控制在输出前添加何种类型的标头。这默认为"salt"
,但也可以设置为"none"
.
进一步注意的是RIJNDAEL_128
意味着密钥长度为 16,而Crypt::CBC
假设密钥长度为32
.
Using Crypt::Rijndael https://metacpan.org/pod/Crypt%3a%3aRijndael没有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
.