我必须使用SHA256 HMAC在Perl中创建哈希,例如以下PHP示例:
<?php
$key = pack('H*','THIS_IS_KEY');
$str ='THIS IS DE ENCODED STRING';
echo strtoupper(hash_hmac('sha256',$str, $key));
?>
我得到:601B7C81389A37FC83C05275138280E8788CF9108528BC75D5C09CEA75904D5E
但是,如果我在Perl脚本中执行相同的操作:
use Digest::SHA qw(hmac_sha256_hex);
my $key = pack('H*','THIS_IS_KEY');
my $str ='THIS IS DE ENCODED STRING';
print uc(hmac_sha256_hex($str, $key));
exit;
我得到:C683FD81DEFB7CDA3C031F5280682E80851FDC246310DB8C44057BC6364454E0
如果我不打包密钥,Perl或PHP都不会得到相同的结果,不幸的是,我必须生成与使用PHP“ pack”的示例完全相同的结果。
如果有人可以帮助我找到解决方案,我将不胜感激。
提前致谢
韦尔奇
代码不了解该pack()
函数的实际工作方式。关键是PHP和Perl脚本之间的区别是什么,因此我们将其简化为该计算。这是一个更简单的PHP程序:
<?php
$key = pack('H*', 'THIS_IS_KEY');
echo $key;
?>
如果将其回显到php | hexdump
,则会得到:
00000000 0000 0000 000e
这是一个类似的Perl程序:
my $key = pack('H*', 'THIS_IS_KEY');
print $key;
如果将其回显到perl | hexdump
,我们将得到:
0000000 2cd1 cff2 204e
这是两个明显不同的键。在这两种情况下,pack()
调用都使用一种H*
格式,这意味着pack()
期望接收到无限制的十六进制字符串(包含十六进制字符0-9A-F的字符串)。问题在于这'THIS_IS_KEY'
不是十六进制值的序列(“ E”除外)。如果通过php
二进制文件本身运行测试代码,您还将看到以下几行:
PHP Warning: pack(): Type H: illegal hex digit T in - on line 2
PHP Warning: pack(): Type H: illegal hex digit H in - on line 2
PHP Warning: pack(): Type H: illegal hex digit I in - on line 2
PHP Warning: pack(): Type H: illegal hex digit S in - on line 2
PHP Warning: pack(): Type H: illegal hex digit _ in - on line 2
PHP Warning: pack(): Type H: illegal hex digit I in - on line 2
PHP Warning: pack(): Type H: illegal hex digit S in - on line 2
PHP Warning: pack(): Type H: illegal hex digit _ in - on line 2
PHP Warning: pack(): Type H: illegal hex digit K in - on line 2
PHP Warning: pack(): Type H: illegal hex digit Y in - on line 2
请注意,除了“ E”之外,都是每个字符都会引发错误,并且请注意,在您的十六进制输出中,除“ E”之外,每个字符都会转换为空半字节。Perl实际上尝试制作一些无意义的字符并将其转换为它可以使用的某种表示形式(例如,“ K”变为4,这是有道理的,因为它是F之后的第5个字符,它对应于十六进制的14)。无论如何,应该向行为传递不匹配格式的字符串是不确定的。
那么,您有什么解决方案?
好吧,如果您真的需要保留'THIS_IS_KEY'
键,那么等效的Perl键是'000000000E0'
。如果您的示例键只是键值的表示形式,则通常在Perl脚本中将PHP键中的非十六进制字符替换为“ 0”。PHP似乎将十六进制字符串中的非十六进制字符视为“ 0”。
对于真正的解决方案,在将传递给之前,要么将您的字符串键转换为十六进制表示形式,要么使用正十六进制值作为键pack()
。我不知道键选择的详细信息,也不知道为什么为什么要打包“键”。代码的SHA256部分仅将字节字符串作为键。只要这两个脚本使用相同的字节序列,它就可以是纯ASCII密钥。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句