Perl 为什么HMAC SHA-1会返回具有相同输入的不同摘要?

Perl 为什么HMAC SHA-1会返回具有相同输入的不同摘要?,perl,encryption,hmac,digest,sha1,Perl,Encryption,Hmac,Digest,Sha1,我正在尝试为AmazonS3Web服务构建一个有效的加密签名,使用Objective C编写一个连接库 我在ObjC代码中遇到了HMAC SHA-1摘要问题,因此我将把它放在一边,并查看现有的、正在运行的Perl代码,以尝试对摘要创建进行故障排除 我正在测试Net::Amazon::S3包的s3ls命令的HMAC SHA-1摘要输出,并将其与我取出并放入自己的perl脚本中的\u encode子例程进行比较: #!/usr/bin/perl -w

我正在尝试为AmazonS3Web服务构建一个有效的加密签名,使用Objective C编写一个连接库

我在ObjC代码中遇到了HMAC SHA-1摘要问题,因此我将把它放在一边,并查看现有的、正在运行的Perl代码,以尝试对摘要创建进行故障排除

我正在测试
Net::Amazon::S3
包的
s3ls
命令的HMAC SHA-1摘要输出,并将其与我取出并放入自己的perl脚本中的
\u encode
子例程进行比较:

#!/usr/bin/perl -w                                                                                                                                                                                    

use MIME::Base64 qw(encode_base64);
use Digest::HMAC_SHA1;
use String::Escape qw( printable unprintable );

sub _ascii_to_hex {
    (my $str = shift) =~ s/(.|\n)/sprintf("%02lx", ord $1)/eg;
    return $str;
}

sub _encode {
    my ( $aws_secret_access_key, $str ) = @_;
    print "secret key hex: "._ascii_to_hex($aws_secret_access_key)."\n";
    my $hmac = Digest::HMAC_SHA1->new($aws_secret_access_key);
    $hmac->add($str);
    my $digest = $hmac->digest;
    print "cleartext hex: "._ascii_to_hex($str)."\n";
    print "digest hex: "._ascii_to_hex($digest)."\n";
    my $b64 = encode_base64( $digest, '' );
    print "encoded: ".$b64."\n";
}

my $secret = "abcd1234";
my $cleartext = "GET\n\n\nFri, 12 Dec 2008 10:08:51 GMT+00:00\n/";
_encode($secret, $cleartext);
以下是此脚本的示例输出:

$ ./testhmac.pl 
secret key hex: 6162636431323334
cleartext hex: 4745540a0a0a4672692c2031322044656320323030382031303a30383a353120474d542b30303a30300a2f
digest hex: 63308f9b8a198440d6d8685a3f3f70d0aab02f68
encoded: YzCPm4oZhEDW2GhaPz9w0KqwL2g=
我正在测试的是,如果我将相同的密钥和明文输入到
Net::Amazon::S3
包的相同
\u encode
函数中,我应该会看到非常相同的密钥、明文和摘要字节

实际上,我得到的密钥和明文的字节是相同的

但是我在摘要中得到了一些不同的东西(当然还有base64编码),例如:

我已经验证了密钥和明文是两个脚本的相同输入。编码子例程在两个脚本中几乎完全相同(除了传递给子例程的未使用参数,我从自定义版本中删除了该参数)

如果输入字节和
\u encode
子例程相同,在这两种情况下,是什么导致HMAC SHA-1摘要的计算不同


(我还根据上的测试用例验证了这两个脚本。)

我恐怕在这里帮不了什么忙,但您发布的内容肯定有问题。您的示例脚本为我生成了不同的输出,您发布的输出确实不正确

这怎么可能

secret key hex: abcd...1234
结果是什么

_ascii_to_hex("blahblahblah")

当然,整个ascii-to-hex问题与您的问题完全无关,但它表明您应该仔细检查您的结果。

我发现在比较中我遇到的哈希的主要问题是:

  • 确保两个比较中的数据和键相同
  • 确保数据和密钥在两次比较中使用相同的字符编码
  • 确保在两个脚本中传递的键和文本是相同的,即哪个是键,哪个是文本(我不止一次发现了这一点)
  • 尝试使用Digest::SHA模块为您创建哈希,并将结果与之进行比较

    use Digest::SHA qw(hmac_sha1_hex);
    my $hash = hmac_sha1_hex($data, $key);
    
    请参见文档中的“分而治之”

    RFC中的测试向量是最好的起点。他们两次都通过了吗?你试过哪些?如果一些有效,而另一些无效,最可能的问题是两个API中的一个未正确编组密钥输入(有符号数组与无符号数组、字符集转换..等等)

    顺便说一句,当你的例子毫无意义时,帮助你真的很困难。正如其他人提到的,blah blah的十六进制表示不是abc..123。让我想知道你的例子中还有什么是不准确的

    编码子例程在两个脚本中几乎完全相同(除了传递给子例程的未使用参数,我从自定义版本中删除了该参数)

    因为您不是在比较摘要本身,而是在比较摘要的Base-64编码版本,所以我建议备份一个步骤并检查摘要本身。Base-64编码例程可能不正确


    如果您不能比较摘要本身,那么在两个程序中使用相同的编码例程,看看您得到了什么。

    1。数据(“明文”)和密钥(“密钥”)在两个比较2中是相同的。我在这两种情况下都使用UTF8字符串3。正如_ascii_to_hex结果所示,用作HMAC实例输入的密钥和明文的字节是相同的,也许不同的Perl模块会有所帮助。AFAIK,Digest::HMAC_SHA1在内部使用Digest::SHA。
    use Digest::SHA qw(hmac_sha1_hex);
    my $hash = hmac_sha1_hex($data, $key);