Skip to content

Instantly share code, notes, and snippets.

@ardenpm
Created January 23, 2020 08:47
Show Gist options
  • Save ardenpm/2d7edaf11c7778191da9f1af1a27d6af to your computer and use it in GitHub Desktop.
Save ardenpm/2d7edaf11c7778191da9f1af1a27d6af to your computer and use it in GitHub Desktop.
/******************************************************************************
* Copyright 2010-2020 migenius pty ltd, Australia. All rights reserved.
*****************************************************************************/
window = {}; // required to allow Forge to load
const forge = require('forge/index');
const s3_config = require('./s3_config.json');
function hmac_sha256(key, data) {
let hmac = forge.hmac.create();
hmac.start('sha256', key);
hmac.update(data);
return hmac.digest().getBytes();
}
function hash_sha256(data) {
let sha = forge.md.sha256.create();
sha.update(data);
return sha.digest().toHex();
}
module.exports.command = {
name: 'aws_s3_v4_get',
description: 'Make get request to AWS S3 using V4 signature signing.',
groups: ['aws', 's3', 'javascript'],
arguments: {
bucket: {
description: 'AWS S3 bucket containing the object to retrieve.',
type: 'String'
},
key: {
description: 'Key which uniquely identifies an object within a bucket, excluding any leading slash.',
type: 'String'
}
},
returns: {
type: 'String',
description: 'String returned by command'
},
execute: function({ bucket, key }) {
const region = 'us-east-1';
const host = `${bucket}.s3.amazonaws.com`;
const url = `https://${host}/${key}`;
const path = `/${bucket}/${key}`;
const algorithm = 'AWS4-HMAC-SHA256';
const time = new Date();
const date = time.toISOString().slice(0,10).replace(/-/g,"");
const time_stamp = time.toISOString().replace(/[-:]/g, '').split('.')[0] + 'Z';
const scope = `${date}/${region}/s3/aws4_request`;
// The canonical request
const hashed_payload = hash_sha256('');
const http_method = 'GET';
const canonical_uri = `/${key}`;
const canonical_query_string = '';
const canonical_headers = `host:${host}\nx-amz-content-sha256:${hashed_payload}\nx-amz-date:${time_stamp}\n`;
const signed_headers = 'host;x-amz-content-sha256;x-amz-date';
const request = http_method + '\n' + canonical_uri + '\n' + canonical_query_string + '\n' + canonical_headers + '\n' + signed_headers + '\n' + hashed_payload;
const canonical_request = hash_sha256(request);;
console.log(`request: ${request}`);
// The signing key
const signing_key = hmac_sha256(hmac_sha256(hmac_sha256(hmac_sha256(`AWS4${s3_config.secret}`,date),'us-east-1'),'s3'),'aws4_request');
// Sign the string and create authorization header
const string_to_sign = `AWS4-HMAC-SHA256\n${time_stamp}\n${scope}\n${canonical_request}`;
const signature = forge.util.bytesToHex(hmac_sha256(signing_key, string_to_sign));
console.log(`string to sign: ${string_to_sign}`);
console.log(`signature: ${signature}`);
// NOTE: if retrieving a binary be sure to set encoding:null
const responses = http.get({
url: url,
headers: {
'Host': host,
'x-amz-content-sha256': hashed_payload,
'x-amz-date': time_stamp,
'Authorization': `AWS4-HMAC-SHA256 Credential=${s3_config.key}/${date}/${region}/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=${signature}`
}
});
return responses;
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment