Skip to content

Instantly share code, notes, and snippets.

@nathancahill
Created May 7, 2019 16:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nathancahill/d387d4f776f455067dc06b9f5996b62b to your computer and use it in GitHub Desktop.
Save nathancahill/d387d4f776f455067dc06b9f5996b62b to your computer and use it in GitHub Desktop.
Modern Node function for signing AWS REST HTTP request parameters with Version 2 Signature
const crypto = require('crypto')
module.exports = (host, method, url, params, awsAccessKeyId, awsSecretAccessKey) => {
const timestamp = (new Date()).toISOString()
const newParams = `${params}&Timestamp=${timestamp}&AWSAccessKeyId=${awsAccessKeyId}`
const sortedParams = newParams
.split('&')
.map(a => {
const [k, v] = a.split('=')
const param = `${k}=${encodeURIComponent(v)}`
return { param, ascii: param.split('').map(g => g.charCodeAt()).join(',') }
})
.sort((a, b) => {
return a.ascii.localeCompare(b.ascii, 'en', { numeric: true })
})
.map(a => a.param)
.join('&')
const toSign = `${method}\n${host}\n${url}\n${sortedParams}`
const signature = crypto.createHmac('sha256', awsSecretAccessKey).update(toSign).digest('base64')
return encodeURIComponent(signature)
}
const signParams = require('./sign')
const AWS_ACCESS_KEY_ID = 'AKIAIOSFODNN7EXAMPLE'
const AWS_SECRET_ACCESS_KEY = '1234567890'
const params = 'SignatureVersion=2&SignatureMethod=HmacSHA256&Version=2009-04-15&Version=2009-04-15'
const signature = signParams('sdb.amazonaws.com', 'GET', '/onca/xml', params, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY))
@nathancahill
Copy link
Author

Correctly sorts and orders AWS REST HTTP parameters by byte value. Correctly escapes and URL-encodes parameter values.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment