为什么HMAC SHA-1会返回具有相同输入的不同摘要? [英] Why would HMAC SHA-1 return a different digest with the same input?

查看:169
本文介绍了为什么HMAC SHA-1会返回具有相同输入的不同摘要?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为Amazon S3 Web服务构建一个加密的签名,使用Objective C编写连接库。



我遇到了HMAC SHA-1消除ObjC代码的问题,所以我把它放在一边,看看现有的Perl代码,尝试排除摘要创建问题。



我正在测试HMAC SHA-1从 s3ls 命令的 Net :: Amazon :: S3 包中输出,并将其与我已经把它放入自己的perl脚本中的 _encode 子例程:

 #!/ usr / bin / perl -w 

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

sub _ascii_to_hex {
(my $ str = shift)=〜s /(。| \\\
)/ sprintf(%02lx,ord $ 1)
return $ str;
}

sub _encode {
my($ aws_secret_access_key,$ str)= @_;
打印密钥十六进制:._ascii_to_hex($ aws_secret_access_key)。\\\
;
my $ hmac = Digest :: HMAC_SHA1-> new($ aws_secret_access_key);
$ hmac-> add($ str);
我的$ digest = $ hmac-> digest;
打印cleartext hex:._ascii_to_hex($ str)。\\\
;
printdigest hex:._ascii_to_hex($ digest)。\\\
;
我的$ b64 = encode_base64($ digest,'');
打印encoded:。$ b64。\\\
;
}

我的$ secret =abcd1234;
我的$ cleartext =GET\\\
\\\
\\\
Fri,2008年12月12日10:08:51 GMT + 00:00\\\
/;
_encode($ secret,$ cleartext);

以下是此脚本的示例输出:

  $ ./testhmac.pl 
的秘密密钥己烷:6162636431323334
明文己烷:4745540a0a0a4672692c2031322044656320323030382031303a30383a353120474d542b30303a30300a2f
消化己烷:63308f9b8a198440d6d8685a3f3f70d0aab02f68
编码:YzCPm4oZhEDW2GhaPz9w0KqwL2g =

我正在测试的是,如果我输入相同的密钥,并将明文输入相同的 _encode 函数的 Net :: Amazon :: S3 包,我应该看到相同的秘密密钥,明文和摘要



的确,我得到相同的字节的秘密密钥和明文。



但我得到的东西例如:

  $ s3ls --access-key = foobar  - secret-key = abcd1234 
...
秘密密钥hex:6162636431323334
cleartext hex:4745540a0a0a4672692c20313220446563203230303 82031303a30383a353120474d542b30303a30300a2f
摘要十六进制:c0da50050c451847de7ed055c5286de584527a22
编码:wNpQBQxFGEfeftBVxSht5YRSeiI =

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



什么将导致HMAC SHA如果输入的字节和 _encode 子程序是相同的,那么在两种情况下都可以不同地计算-1 digest,



(我也已经在 RFC 2201 上验证了两个测试用例脚本。)

解决方案

我发现比较中散列的主要问题是:


  1. 确保数据和密钥在两个比较中都相同

  2. 确保数据和密钥在两个比较中都是相同的字符编码

  3. 确保两个脚本中的键和文本都被传递相同,即哪一个是键,哪个是文本(这已经被我抓住了一次以上)。

尝试我们使用Digest :: SHA模块为您创建哈希值并与之结果进行比较。

  use Digest :: SHA qw (hmac_sha1_hex); 
我的$ hash = hmac_sha1_hex($ data,$ key);

请参阅 http://perldoc.perl.org/Digest/SHA.pdf


I am trying to build a working encrypted signature for the Amazon S3 web service, writing a connection library using Objective C.

I have run into HMAC SHA-1 digest problems with the ObjC code, so I'm putting that to the side and looking at existing, working Perl code, to try to troubleshoot digest creation.

I am testing HMAC SHA-1 digest output from the s3ls command of the Net::Amazon::S3 package and comparing that against the _encode subroutine that I pulled out and put into its own perl script:

#!/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);

Here is sample output from this script:

$ ./testhmac.pl 
secret key hex: 6162636431323334
cleartext hex: 4745540a0a0a4672692c2031322044656320323030382031303a30383a353120474d542b30303a30300a2f
digest hex: 63308f9b8a198440d6d8685a3f3f70d0aab02f68
encoded: YzCPm4oZhEDW2GhaPz9w0KqwL2g=

What I am testing is that, if I input the same secret key and cleartext into the same _encode function of the Net::Amazon::S3 package, I should see the very same secret key, cleartext, and digest bytes.

Indeed, I get the same bytes for the secret key and cleartext.

But I get something different for the digest (and of course the base64 encoding), e.g.:

$ s3ls --access-key=foobar --secret-key=abcd1234
...
secret key hex: 6162636431323334
cleartext hex: 4745540a0a0a4672692c2031322044656320323030382031303a30383a353120474d542b30303a30300a2f
digest hex: c0da50050c451847de7ed055c5286de584527a22
encoded: wNpQBQxFGEfeftBVxSht5YRSeiI=

I have verified that the secret key and clear text are the same input to both scripts. The encoding subroutine is virtually identical in both scripts (except for an unused argument passed to the subroutine, which I remove from my custom version).

What would cause the HMAC SHA-1 digest to be computed differently in both cases, if the input bytes and _encode subroutine are the same?

(I have also verified the two scripts against the test cases at RFC 2201.)

解决方案

I find the the main problems I have had with hashes in comparisons are:

  1. ensure the data and key are the same in both comparisons
  2. ensure the data and key are in the same character encoding in both comparisons
  3. ensure the key and text are being passed the same in both scripts, i.e. which one is key and which one is text (this has caught me more than once).

Try using the Digest::SHA module to create the hash for you and compare the results with that.

use Digest::SHA qw(hmac_sha1_hex);
my $hash = hmac_sha1_hex($data, $key);

See docs at http://perldoc.perl.org/Digest/SHA.pdf

这篇关于为什么HMAC SHA-1会返回具有相同输入的不同摘要?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆