Не удалось сгенерировать подпись для AWS версия подписи 4 в Javascript Angular 8 - PullRequest
0 голосов
/ 27 февраля 2020
  1. Это мой сервис в angular 8. Для генерации заголовка для метода HTTP. Это дает мне ошибку для подписи, не совпадающей с сгенерированной мной подписью. С

accessKeyId: "AKIA ******* UTIZO5UUP", secretAccessKey: "n5bndDO *************** xb3IA0GvmAVTOaDLNDG"

execute(credentials, request) {
    let url = new URL(request.url);
    let date = new Date();
    credentials.host = url.host;
    request.route = url.pathname;

    let canonical = this.canonicalRequest(credentials, request, date);
    console.log("canonical: ", canonical);
    let toSign = this.requestToSign(canonical, credentials, date);
    console.log("toSign: ", toSign);
    let signature = this.signature(toSign, credentials, date);
    console.log("signature: ", signature);

    return {
      "x-amz-date": this.amzLongDate(date),
      Authorization:
        "AWS4-HMAC-SHA256 Credential=" +
        credentials.accessKeyId +
        "/" +
        this.amzShortDate(date) +
        "/" +
        credentials.region +
        "/execute-api/aws4_request, " +
        ("SignedHeaders=content-type;host;x-amz-date" +
          (credentials.token ? "x-amz-security-token" : "") +
          ", Signature=" +
          signature),
      "Content-Type": "application/json",
      "x-amz-security-token": credentials.token || undefined
      // host: this.credentials.host,
    };
  }

  canonicalRequest(credentials, request, date) {
    return (
      "\n" +
      this.request.method.toUpperCase() +
      "\n" +
      (request.route.charAt(0) !== "/" ? "/" + request.route : request.route) + //
      "\n" +
      this.queryParameters(request.query) +
      "\ncontent-type:application/json\nhost:" +
      credentials.host +
      "\n" +
      ("x-amz-date:" +
        this.amzLongDate(date) +
        "\n" +
        (credentials.token
          ? "x-amz-security-token:" + credentials.token + "\n"
          : "") +
        "\n") +
      ("content-type;host;x-amz-date" +
        (credentials.token ? ";x-amz-security-token" : "") +
        "\n") +
      this.hashString(this.request.body)
    );
  }

  requestToSign(cRequest, credentials, date) {
    return (
      "\n" +
      "AWS4-HMAC-SHA256\n" +
      this.amzLongDate(date) +
      "\n" +
      this.amzShortDate(date) +
      "/" +
      credentials.region +
      "/execute-api/aws4_request\n" +
      this.hashString(cRequest)
    );
  }

  signature(toSign, credentials, date) {
    return this.hmac(
      this.hmac(
        this.hmac(
          this.hmac(
            this.hmac(
              "AWS4" + credentials.secretAccessKey,
              this.amzShortDate(date)
            ),
            credentials.region
          ),
          "execute-api"
        ),
        "aws4_request"
      ),
      toSign
    ).toString();
  }

  queryParameters(queryParameterObj) {
    var pieces = [];
    if (queryParameterObj) {
      Object.keys(queryParameterObj)
        .sort()
        .forEach(function(k) {
          return pieces.push(
            k + "=" + encodeURIComponent(queryParameterObj[k])
          );
        });
    }
    return pieces.length > 0 ? pieces.join("&") : "";
  }

  hashString(str) {
    return CryptoJS.SHA256(str).toString();
  }

  hmac(key, value) {
    return CryptoJS.HmacSHA256(value, key);
  }

  amzShortDate(date) {
    return this.amzLongDate(date).substr(0, 8);
  }

  amzLongDate(date) {
    return date
      .toISOString()
      .replace(/[:\-]|\.\d{3}/g, "")
      .substr(0, 17);
  }
Тогда это мой объект для метода, с помощью которого я бы вызвал метод execute
credentials = {
    region: "us-east-1",
    accessKeyId: "AKIA*******UTIZO5UUP",
    secretAccessKey: "n5bndDO***************xb3IA0GvmAVTOaDLNDG",
    host: "",
    token: null
  };
  request = {
    url:
      "https://jml******xa.execute-api.us-east-1.amazonaws.com/name-of-app/review/v1",
    type: "GET",
    method: "GET",
    dataType: "json",
    contentType: "application/json",
    data: { foo: "bar" },
    route: "",
    query: null,
    body: null
  };
Проблема в том, что я могу получить правильный canonicalRequest и requestToSign, но подпись не совпадает, как говорится ....
{
    "message": "The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.\n\nThe Canonical String for this request should have been\n'GET\n/name-of-app/review/v1\n\ncontent-type:application/json\nhost:jq******xa.execute-api.us-east-1.amazonaws.com\nx-amz-date:20200227T162638Z\n\ncontent-type;host;x-amz-date\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'\n\nThe String-to-Sign should have been\n'AWS4-HMAC-SHA256\n20200227T162638Z\n20200227/us-east-1/execute-api/aws4_request\n9f4671025ee537c0253df73dc1c673d30e22966b3ac544f03df14e3b85f76238'\n"
}
...