加密地穴-尝试以与Perl相同的方式在PHP中工作

我已经在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,文档提供以下信息:

string mcrypt_encrypt ( string $cipher , string $key , string $data , string $mode [, string $iv ] )

  • $cipher is the algorithm name.
  • $key is the encryption key, if it is too short it will be padded with NUL bytes.
  • $data is the data to be encrypted, if it is too short it will be padded with NUL bytes.
  • $mode is the mode of operation, here "cbc" is correct.
  • $iv is the initialization vector, if not provided it will be initialized as NUL bytes.

对于Crypt::CBC,我们改为使用以下行为:

Crypt::CBC->new(KEYWORD_OPTIONS)

  • -key => STRING is the passphrase from which the encryption key is generated by some hashing operations.
  • -literal_key => BOOL If set, this skips the hashing for the -key and uses it as a literal key.
  • -cipher => CIPHER the name of a cipher, or a pre-initialized cipher object.
  • -salt => 1 | STRING If set to "1", this will produce a random salt. Any other values are taken as the literal salt. This defaults to -salt => 1 if a salt is needed. Or something like that, the docs are a bit confusing here. The salt is not needed if both the -iv and literal_key options are set.
  • -iv => STRING is the initialization vector, which is usually generated from the salt.
  • -header => STRING controls what kind of header is prepended to the output. This defaults to "salt", but can also be set to "none".

还要注意,RIJNDAEL_128的密钥长度为16,而Crypt :: CBC的密钥长度为32.

最好使用不带Crypt :: CBC包装器的Crypt::Rijndael,因为这使我们可以轻松地将必需的选项设置为与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.

上一篇:python-VBA中的HMAC-SHA1 URL加密产生不正确的输出


下一篇:php-将自动递增ID转换为9位随机序列号