我使用openssl_encrpyt在PHP中加密客户端编号。
$value = '01715034842';
$key = 'pi3kn3W@k@cj3';
$iv = 'Toy@dtv!';
$cipher = 'bf-cbc';
$crypted = openssl_encrypt($value, $cipher, $key, true, $iv);
$hashValue = unpack('H*',$crypted);
最终结果是: 0b6b81176ac7c298ebcb294f0a581539
我的朋友也在Pearl编程其他部分。而且他还使用相同的键并使用Blowfish对相同的数字进行编码(他使用的是Pearl库:https://metacpan.org/pod/release/LDS/Crypt-CBC-2.30/CBC.pm):
use Crypt::CBC;
use Crypt::Blowfish;
## szyfrowanie
my $key = 'pi3kn3W@k@cj3';
my $iv = 'Toy@dtv!';
my $cipher = Crypt::CBC->new( -key => $key,
-iv => $iv,
-header => 'none',
-cipher => 'Blowfish'
);
sub mkHash {
my $crypt = $cipher->encrypt_hex($_[0]);
# print 'Hash: '.$crypt."\n";
return $crypt;
}
sub deHash {
my $crypt = $cipher->decrypt_hex($_[0]);
# print 'string: '.$crypt."\n";
return $crypt;
}
my $clientHash = mkHash($smc);
他对于同一组数据得到不同的结果: c5377bcf0f55af641709c35928350576
所以我们不能广泛使用这种毛毯。 这取决于编程语言的差异吗?还是这是我的代码或语言中的错误? 我认为,当我们使用相同的数据集和相同的加密(BlowFish CBC)时,每种语言都应获得相同的结果。
期待对此案发表意见。
最佳 Bartek。
答案 0 :(得分:2)
以下PHP和Perl脚本显示了如何为两种语言实现相同的输出。我将在下面解释一些细节。
PHP:
$value = '01715034842';
$cipher = 'bf-cbc';
$key = '12345678901234567890123456789012345678901234567890123456';
$option = OPENSSL_RAW_DATA;
$iv = 'Toy@dtv!';
$crypted = openssl_encrypt($value, $cipher, $key, $option, $iv);
echo($crypted)
Perl:
use Crypt::CBC;
use Crypt::Blowfish;
my $value = '01715034842';
my $key = '12345678901234567890123456789012345678901234567890123456';
my $iv = 'Toy@dtv!';
my $cipher = Crypt::CBC->new( -literal_key => 1,
-key => $key,
-iv => $iv,
-header => 'none',
-cipher => 'Blowfish'
);
my $crypted = $cipher->encrypt($value);
print $crypted;
在两个输出上使用diff
不会产生任何差异,表明它们是相同的:
$ diff <(php encrypt.php) <(perl encrypt.pl)
$
以下各节说明了与原始代码相比所需的更改。
加密密钥
PHP openssl_encrypt()
函数始终期望使用原始密钥。您提供的字节是用作加密密钥的字节。另一方面,Perl CBC
类是expects a passphrase by default类,它将从中派生加密密钥by doing an MD5 hash。如果要让类使用原始字节作为加密密钥,则必须将参数literal_key
设置为1
。
完成此操作后,CBC
类将期望密钥为加密方案which the CBC
class assumes to be 56
for the Crypt::Blowfish
implementation所需的确切字节数。因此,脚本中的调整键。否则将得到的错误是If specified by -literal_key, then the key length must be equal to the chosen cipher's key length of 56 bytes
输出格式
默认情况下,PHP openssl_encrypt()
函数返回base64编码的字符串,CBC
类返回原始字节。保持一致的一种方法是通过在PHP中设置OPENSSL_RAW_DATA
选项。
检查密文
如果要检查可读格式的密文,则可以在末尾添加自己的打印例程,或者将输出通过管道传输到hexdump
或xxd
之类的工具中
$ php encrypt.php | xxd
00000000: 5f35 3205 74e8 dcaa 2f05 9aa4 366e ef8b _52.t.../...6n..
$ perl encrypt.pl | xxd
00000000: 5f35 3205 74e8 dcaa 2f05 9aa4 366e ef8b _52.t.../...6n..