为什么 HMAC SHA-1 使用相同的输入返回不同的摘要?

发布于 2024-07-09 20:34:44 字数 2357 浏览 9 评论 0原文

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

我在 ObjC 代码中遇到了 HMAC SHA-1 摘要问题,所以我将其放在一边并查看在现有的工作 Perl 代码中,尝试解决摘要创建问题。

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

#!/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=

我正在测试的是,如果我将相同的密钥和明文输入到相同的 _encode 函数中在 Net::Amazon::S3 包中,我应该看到完全相同的密钥、明文和摘要字节。

事实上,我得到了相同的密钥和明文字节。

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

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

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

如果输入字节和 _encode 子例程相同,什么会导致 HMAC SHA-1 摘要在两种情况下的计算方式不同?

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

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.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

木緿 2024-07-16 20:34:44

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

  1. 确保两次比较中的数据和密钥相同
  2. 确保两次比较中的数据和密钥采用相同的字符编码
  3. 确保密钥和文本传递相同在这两个脚本中,即哪个是关键,哪个是文本(这已经不止一次地吸引了我)。

尝试使用 Digest::SHA 模块为您创建哈希并将结果与​​其进行比较。

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

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

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

若水微香 2024-07-16 20:34:44

两个脚本中的编码子例程实际上是相同的(除了传递给子例程的未使用的参数,我从自定义版本中删除了该参数)。

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

如果您无法比较摘要本身,请在两个程序中使用相同的编码例程,看看您会得到什么。

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).

Since you're not comparing the digests themselves, but Base-64 encoded versions of the digests, I would recommend backing up one step and checking the digests themselves. It may be possible that the Base-64 encoding routines are incorrect.

If you can't compare the digests themselves, then use the same encoding routine in both programs and see what you get.

じ违心 2024-07-16 20:34:44

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

secret key hex: abcd...1234

结果

_ascii_to_hex("blahblahblah")

当然,整个 ascii_to_hex 的事情与你的问题完全无关,但它表明你应该仔细检查你的

I'm afraid I can't help much here, but there's definitely something wrong with what you posted. Your example script produces different output for me and the output you posted really cannot be correct.

How could this

secret key hex: abcd...1234

ever be the result of that

_ascii_to_hex("blahblahblah")

Of course, the whole ascii_to_hex thing is completely irrelevant to your problem, but it shows that you should double-check your results.

北音执念 2024-07-16 20:34:44

分而治之?

RFC 中的测试向量是最好的起点。 两种情况都通过了吗? 你尝试过哪些? 如果某些工作和其他工作没有,最可能的问题是两个 API 之一不正确地编组键输入(有符号数组与无符号数组、字符集转换等)

顺便说一句,当您的示例是时,它真的很难帮助您废话。 正如其他人提到的,blah blah 的十六进制表示不是 abc..123。 让我想知道您的示例中还有哪些不准确的地方?

Divide and conquer?

The test vectors in the RFC are the best place to start. Did they pass in both instances? Which ones did you try? If some work and others don't the most likely problem is that one of the two APIs are improperly marshalling the keys input (Signed vs unsigned arrays, charset conversions..etc)

As an aside its really difficult to help you when your example is nonsense. As others mentioned the hex representation of blah blah is not abc..123. Makes me wonder what else in your example is inaccurate?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文