无法从亚马逊复制简单的哈希签名示例

Can't replicate simple hashing signature example from Amazon

我正在尝试在 Flutter 中创建此示例的最后一步,但由于某种原因我无法正确完成: https://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html

使用他们的签名密钥 + 字符串进行签名,他们得到了这个签名结果: 5d672d79c15b13162d9279b0855cfba6789a8edb4c82c400e06b5924a6f2b5d7

使用完全相同的密钥/字符串进行签名,我最终得到: fe52b221b5173b501c9863cec59554224072ca34c1c827ec5fb8a257f97637b1

这是我的代码:

var testSigninKey =
'c4afb1cc5771d871763a393e44b703571b55cc28424d1a5e86da6ed3c154a4b9';
var testStringToSign = 'AWS4-HMAC-SHA256' + '\n' +
      '20150830T123600Z'  + '\n' +
      '20150830/us-east-1/iam/aws4_request'  + '\n' +
      'f536975d06c0309214f805bb90ccff089219ecd68b2577efef23edd43b7e1a59';    

var hmac1 = Hmac(sha256, utf8.encode(testSigninKey));
var digest1 = hmac1.convert(utf8.encode(testStringToSign));
print(digest1);
print(hex.encode(digestBytes.bytes));
//both print: fe52b221b5173b501c9863cec59554224072ca34c1c827ec5fb8a257f97637b1

hmac1 调用要求您按原样使用签名密钥,而不是使用它的十六进制字符串表示形式的编码版本。

你应该能够用这个正确地构造 Hmac 对象:

var hmac1 = Hmac(sha256, hex.decode(testSigninKey));

这里是我的flutter代码的完整示例,参考s3签名创建示例: https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html 我知道它并不完美,但我花了很长时间才弄明白。也许对某人有帮助。

import 'dart:convert';

import 'package:convert/convert.dart';
import 'package:crypto/crypto.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:http/http.dart' as http;

class AWS {

  var _algorithm = ["X-Amz-Algorithm", "AWS4-HMAC-SHA256"];
  final String _awsService = "s3";
  final String _aws4Request = "aws4_request";
  var _expires = ["X-Amz-Expires", "86400"];
  var _signedHeaders = ["X-Amz-SignedHeaders", "host"];

  var testbucket = "https://s3.amazonaws.com/examplebucket";
  var testfilePath = "/test.txt";
  var _testDate = ["X-Amz-Date", "20130524T000000Z"];
  var _testDateymd = 20130524;
  var _testRegion = "us-east-1";
  var _testCredential = [
    "X-Amz-Credential",
    "AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request"
  ];
  var testSecretkey = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY";

  testString() {
    var httpMethod = "GET";
    var canUri = testfilePath;
    var canQueryStr = Uri.encodeQueryComponent(_algorithm[0]) +
        "=" +
        Uri.encodeQueryComponent(_algorithm[1]) +
        "&" +
        Uri.encodeQueryComponent(_testCredential[0]) +
        "=" +
        Uri.encodeQueryComponent(_testCredential[1]) +
        "&" +
        Uri.encodeQueryComponent(_testDate[0]) +
        "=" +
        Uri.encodeQueryComponent(_testDate[1]) +
        "&" +
        Uri.encodeQueryComponent(_expires[0]) +
        "=" +
        Uri.encodeQueryComponent(_expires[1]) +
        "&" +
        Uri.encodeQueryComponent(_signedHeaders[0]) +
        "=" +
        Uri.encodeQueryComponent(_signedHeaders[1]);
// <CanonicalQueryString>\n
// <CanonicalHeaders>\n
// <SignedHeaders>\n
// <HashedPayload>
    var _canonicalRequest = httpMethod +
        "\n" +
        canUri +
        "\n" +
        canQueryStr +
        "\n" +
        "host:examplebucket.s3.amazonaws.com" +
        "\n" +
        "\n" +
        "host" +
        "\n" +
        "UNSIGNED-PAYLOAD";
    var bytes = utf8.encode(_canonicalRequest);

    var _stringToSign = "AWS4-HMAC-SHA256" +
        "\n" +
        "20130524T000000Z" +
        "\n" +
        "20130524/us-east-1/s3/aws4_request" +
        "\n" +
        sha256.convert(bytes).toString();
    print("String to sign: $_stringToSign");

//  HEX und HMAC signature

    List<int> _dateKey = utf8.encode("AWS4" + testSecretkey);
    List<int> _dateMsg = utf8.encode(_testDateymd.toString());
    Hmac dateHmac = Hmac(sha256, _dateKey);
    Digest dateDigest = dateHmac.convert(_dateMsg);

    String _dateRegionKey = dateDigest.toString();
    List<int> _dateRegionMsg = utf8.encode(_testRegion.toString());
    Hmac dateRegionHmac = Hmac(sha256, hex.decode(_dateRegionKey.toString()));
    Digest dateRegionDigest = dateRegionHmac.convert(_dateRegionMsg);

    String _dateRegionServiceKey = dateRegionDigest.toString();
    List<int> _dateRegionServiceMsg = utf8.encode(_awsService.toString());
    Hmac dateRegionServiceHmac =
        Hmac(sha256, hex.decode(_dateRegionServiceKey.toString()));
    Digest dateRegionServiceDigest =
        dateRegionServiceHmac.convert(_dateRegionServiceMsg);

    String _signingKey = dateRegionServiceDigest.toString();
    List<int> _signingKeyMsg = utf8.encode(_aws4Request.toString());
    Hmac _signingKeyHmac = Hmac(sha256, hex.decode(_signingKey.toString()));
    Digest _signingKeyDigest = _signingKeyHmac.convert(_signingKeyMsg);

    print("signing key: $_signingKeyDigest");

    var _signatureKey = _signingKeyDigest.toString();
    List<int> _signatureKeyMsg = utf8.encode(_stringToSign);
    Hmac _signatureHmac = Hmac(sha256, hex.decode(_signatureKey));
    var _signature = _signatureHmac.convert(_signatureKeyMsg);

    print("Signature: $_signature");
  }
}