Note that there are some explanatory texts on larger screens.

plurals
  1. POWhy would HMAC SHA-1 return a different digest with the same input?
    text
    copied!<p>I am trying to build a working encrypted signature for the Amazon S3 web service, writing a connection library using Objective C. </p> <p>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.</p> <p>I am testing HMAC SHA-1 digest output from the <code>s3ls</code> command of the <code>Net::Amazon::S3</code> package and comparing that against the <code>_encode</code> subroutine that I pulled out and put into its own perl script:</p> <pre><code>#!/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-&gt;new($aws_secret_access_key); $hmac-&gt;add($str); my $digest = $hmac-&gt;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); </code></pre> <p>Here is sample output from this script:</p> <pre><code>$ ./testhmac.pl secret key hex: 6162636431323334 cleartext hex: 4745540a0a0a4672692c2031322044656320323030382031303a30383a353120474d542b30303a30300a2f digest hex: 63308f9b8a198440d6d8685a3f3f70d0aab02f68 encoded: YzCPm4oZhEDW2GhaPz9w0KqwL2g= </code></pre> <p>What I am testing is that, if I input the same secret key and cleartext into the same <code>_encode</code> function of the <code>Net::Amazon::S3</code> package, I should see the very same secret key, cleartext, and digest bytes.</p> <p>Indeed, I get the same bytes for the secret key and cleartext.</p> <p>But I get something different for the digest (and of course the base64 encoding), e.g.:</p> <pre><code>$ s3ls --access-key=foobar --secret-key=abcd1234 ... secret key hex: 6162636431323334 cleartext hex: 4745540a0a0a4672692c2031322044656320323030382031303a30383a353120474d542b30303a30300a2f digest hex: c0da50050c451847de7ed055c5286de584527a22 encoded: wNpQBQxFGEfeftBVxSht5YRSeiI= </code></pre> <p>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).</p> <p>What would cause the HMAC SHA-1 digest to be computed differently in both cases, if the input bytes and <code>_encode</code> subroutine are the same?</p> <p>(I have also verified the two scripts against the test cases at <a href="http://www.faqs.org/rfcs/rfc2202.html" rel="nofollow noreferrer">RFC 2201</a>.)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload