1

I want upload a file with evaporate.js and crypto-js using x-amz-security-token:

import * as Evaporate from 'evaporate';
import * as crypto from "crypto-js";

Evaporate.create({
  aws_key: <ACCESS_KEY>,
  bucket: 'my-bucket',
  awsRegion: 'eu-west',
  computeContentMd5: true,
  cryptoMd5Method: data => crypto.algo.MD5.create().update(String.fromCharCode.apply(null, new Uint32Array(data))).finalize().toString(crypto.enc.Base64),
  cryptoHexEncodedHash256: (data) => crypto.algo.SHA256.create().update(data as string).finalize().toString(crypto.enc.Hex),
  logging: true,
  maxConcurrentParts: 5,  
  customAuthMethod: (signParams: object, signHeaders: object, stringToSign: string, signatureDateTime: string, canonicalRequest: string): Promise<string> => {
      const stringToSignDecoded = decodeURIComponent(stringToSign)
      const requestScope = stringToSignDecoded.split("\n")[2];
      const [date, region, service, signatureType] = requestScope.split("/");
      const round1 = crypto.HmacSHA256(`AWS4${signParams['secret_key']}`, date);
      const round2 = crypto.HmacSHA256(round1, region);
      const round3 = crypto.HmacSHA256(round2, service);
      const round4 = crypto.HmacSHA256(round3, signatureType);
      const final = crypto.HmacSHA256(round4, stringToSignDecoded);
      return Promise.resolve(final.toString(crypto.enc.Hex));
  },
  signParams: { secretKey: <SECRET_KEY> },
  partSize: 1024 * 1024 * 6
  }).then((evaporate) => {
      evaporate.add({
          name: 'my-key',
          file: file, // file from <input type="file" />
          xAmzHeadersCommon: { 'x-amz-security-token': <SECURITY_TOKEN> },
          xAmzHeadersAtInitiate: { 'x-amz-security-token': <SECURITY_TOKEN> },
       }).then(() => console.log('complete'));
  },
     (error) => console.error(error)
  );

but it produce this output

AWS Code: SignatureDoesNotMatch, Message:The request signature we calculated does not match the signature you provided. Check your key and signing method.status:403

What I'm doing wrong

SIDE NOTE

This is the versione I'm using on browser side:

{
  "crypto-js": "^4.1.1",
  "evaporate": "^2.1.4"
}
ar099968
  • 6,963
  • 12
  • 64
  • 127

1 Answers1

1

You have your crypto.HmacSHA256 parameters reversed. They should all be the other way around. I've been bashing my head against a wall trying to get evaporate 2.x to work for the last week, it's been very frustrating.

I tried your code above and looked over all the docs and forum posts related to this, and I think using Cognito for this auth just doesn't work or isn't obvious how it's supposed to work, even though the AWS docs suggest it's possible.

In the end I went with using Lambda authentication and finally got it working after seeing much misinformation about how to use various crypto libraries to sign this stuff. I got it working last night after rigorously examining every bit of what was going on. Reading the docs also helped get me on the right path as to how the crypto needs to work, it gives example inputs and outputs so you can test for sure that your crypto methods are working as AWS expects them to work:

https://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html

Tasks 1, 2 and 3 are especially important to read and understand.

neimad
  • 594
  • 5
  • 5