Objective Cを使用して接続ライブラリを作成し、AmazonS3Webサービス用に機能する暗号化された署名を作成しようとしています。
ObjCコードでHMACSHA-1ダイジェストの問題が発生したので、それを脇に置いて、既存の動作中のPerlコードを調べて、ダイジェスト作成のトラブルシューティングを試みます。
s3ls
パッケージのコマンドからのHMACSHA-1ダイジェスト出力をテストし、それを引き出して独自のperlスクリプトに入れNet::Amazon::S3
たサブルーチンと比較しています。_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=
私がテストしているのは、同じ秘密鍵とクリアテキストをパッケージの同じ_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のテストケースに対して2つのスクリプトも検証しました。)