Amazon Signature Version 4 Calculation -
i'm trying calculate same situation shown here
following snippet of coffeescirpt uses cryptojs. encodedpolicy correct according example.
hmac = cryptojs.algo.hmac.create(cryptojs.algo.sha256, "aws4" + "wjalrxutnfemi/k7mdeng/bpxrficyexamplekey") hmac.update("20130806") hmac.update("us-east-1") hmac.update("s3") hmac.update("aws4_request") hmac.update(encodedpolicy) console.log( hmac.finalize().tostring() )
the output "71df5c44d375c21856d92de15941bc0deaf1a845e197c7f46834663256092f56", expected "21496b44de44ccb73d545f1a995c68214c9cb0d41c45a17a5daeec0b1a6db047".
update:
getsignaturekey = (key, datestamp, regionname, servicename, encodedpolicy) -> hmac = cryptojs.algo.hmac.create(cryptojs.algo.sha256, "aws4" + key) hmac.update( datestamp ) datekey = hmac.finalize() hmac = cryptojs.algo.hmac.create(cryptojs.algo.sha256, datekey ) hmac.update( regionname ) regionkey = hmac.finalize() hmac = cryptojs.algo.hmac.create(cryptojs.algo.sha256, regionkey ) hmac.update( servicename ) servicekey = hmac.finalize() hmac = cryptojs.algo.hmac.create(cryptojs.algo.sha256, servicekey ) hmac.update( "aws4_request" ) requestkey = hmac.finalize() hmac = cryptojs.algo.hmac.create(cryptojs.algo.sha256, requestkey ) hmac.update( encodedpolicy ) return hmac.finalize()
is correct @ least until requestkey. still getting response amazon saying signature calculated not match 1 provided.
update2: below relevant code.
server code @s3 = {} @s3.key = "aws-key" @s3.privkey = "aws-priv-key" @s3.region = 'us-east-1' @s3.service = 's3' @s3.alg = 'aws4-hmac-sha256' @s3.bucket = 'bucket-name' @s3.acl = 'public-read'
@s3.generate_policy = (path,date) -> policy = { "conditions": [ {'bucket': s3.bucket} ['starts-with', '$key', path] {'acl': s3.acl} {'success_action_status': '200'} ["content-length-range", 0, 100000] ['starts-with', '$content-type', 'image/jpeg'] ] "expiration": date.format("yyyy-mm-ddthh:mm:ss.00\\z") } return policy getsignaturekey = (key, datestamp, regionname, servicename, stringtosign) -> hmac = cryptojs.algo.hmac.create(cryptojs.algo.sha256, "aws4" + key) hmac.update( datestamp ) datekey = hmac.finalize() hmac = cryptojs.algo.hmac.create(cryptojs.algo.sha256, datekey ) hmac.update( regionname ) regionkey = hmac.finalize() hmac = cryptojs.algo.hmac.create(cryptojs.algo.sha256, regionkey ) hmac.update( servicename ) servicekey = hmac.finalize() hmac = cryptojs.algo.hmac.create(cryptojs.algo.sha256, servicekey ) hmac.update( "aws4_request" ) requestkey = hmac.finalize() hmac = cryptojs.algo.hmac.create(cryptojs.algo.sha256, requestkey ) hmac.update( stringtosign ) return hmac.finalize() stringtosign = (alg, date, creds, hashedreq) -> return alg + '\n' + date.format( "yyyymmddthhmmss\\z" ) + '\n' + creds + '\n' + hashedreq canonreq = (date, creds, alg) -> headers = "host: " + s3.bucket + ".s3.amazonaws.com" + '\n' headers += "content-type: image/jpeg; charset=utf-8" + '\n' headers += "x-amz-date: " + date.format("yyyymmddthhmmss\\z") + '\n' signedheaders = "content-type;host;x-amz-date" canonreq = "post http://" + s3.bucket + ".s3.amazonaws.com/ http/1.1" + '\n' canonreq += "\\" + '\n' canonreq += '\n' canonreq += headers canonreq += '\n' canonreq += signedheaders + '\n' canonreq += cryptojs.sha256( signedheaders ) @s3.generate_credentials = (path, date) -> policy = new buffer(json.stringify(s3.generate_policy(path, date )).replace('\n', "")).tostring('base64') creds = s3.key + '/' + date.format("yyyymmdd") + '/' + s3.region + '/' + s3.service + '/' + 'aws4_request' hashedcanonicalreq = cryptojs.sha256( canonreq(date) ) stringtosign = stringtosign( s3.alg, date, creds, hashedcanonicalreq ) sig = getsignaturekey(s3.privkey,date.format('yyyymmdd'),s3.region,s3.service, stringtosign) credentials = { awskey: s3.key key: path policy: policy bucket: s3.bucket signature: sig.tostring() acl: s3.acl date: date.format("yyyymmddthhmmss\\z") alg: s3.alg creds: creds } return credentials @meteor.methods get_s3_credentials: () -> if !meteor.user() return path = "test" date = moment().utc().add('minutes', 5) credentials = s3.generate_credentials(path, date) return credentials
client code
uploadfile = function() { meteor.call( 'get_s3_credentials', function(err, res) { if( res ){ var file = document.getelementbyid('uploadfiles').files[0]; var fd = new formdata(); console.log( res ); fd.append('key',res.key); fd.append('awsaccesskeyid', res.awskey) fd.append('acl',res.acl); fd.append('signature',res.signature); fd.append('policy', res.policy); fd.append('success_action_status',200); fd.append('content-type',"image/jpeg"); fd.append("file",file); var xhr = new xmlhttprequest(); xhr.open('post', 'https://' + res.bucket + '.s3.amazonaws.com', true); xhr.send(fd); }else{ console.log( err ); } }); }
update: able working using aws-sdk (signed url) , client side code http://www.recursiverobot.com/post/75281512146/demos-using-aws-with-node-js-and-an-angularjs-frontend#s3.
Comments
Post a Comment