5

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つのスクリプトも検証しました。)

4

4 に答える 4

3

比較でハッシュに関して私が抱えていた主な問題は次のとおりです。

  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のドキュメントを参照してください

于 2008-12-12T12:16:44.120 に答える
2

エンコーディングサブルーチンは、両方のスクリプトで実質的に同じです(サブルーチンに渡された未使用の引数を除いて、カスタムバージョンから削除します)。

ダイジェスト自体を比較しているのではなく、Base-64でエンコードされたバージョンのダイジェストを比較しているので、1つの手順をバックアップして、ダイジェスト自体を確認することをお勧めします。Base-64エンコーディングルーチンが正しくない可能性があります。

ダイジェスト自体を比較できない場合は、両方のプログラムで同じエンコーディングルーチンを使用して、何が得られるかを確認してください。

于 2008-12-12T21:10:00.160 に答える
1

分割統治?

RFCのテストベクトルは、開始するのに最適な場所です。それらは両方のインスタンスで合格しましたか?どれを試しましたか?一部の作業と他の作業で最も可能性の高い問題がない場合は、2つのAPIのいずれかが入力されたキーを不適切にマーシャリングしていることです(符号付き配列と符号なし配列、文字セット変換など)

余談ですが、あなたの例がナンセンスであるときにあなたを助けることは本当に難しいです。他の人が述べたように、何とか何とか何とかの16進表現はabc..123ではありません。あなたの例の他に何が不正確であるのか疑問に思いますか?

于 2008-12-12T12:24:17.803 に答える
1

申し訳ありませんが、ここではあまり役に立ちませんが、投稿した内容には間違いなく何か問題があります。あなたのサンプルスクリプトは私にとって異なる出力を生成し、投稿した出力は実際には正しくありません。

これはどうして

secret key hex: abcd...1234

その結果になることはありません

_ascii_to_hex("blahblahblah")

もちろん、 ascii_to_hex 全体は問題とはまったく関係ありませんが、結果を再確認する必要があることを示しています。

于 2008-12-12T11:26:22.157 に答える