使用Javascript创建签名的S3 URL

Kit*_*Kit 6 javascript encryption amazon-s3 amazon-web-services

我正在尝试使用Javascript和NodeJS创建签名的S3 URL.我使用过 这个 规范.

var crypto     = require('crypto'),
    date       = 1331290899,
    resource   = '/myfile.txt',
    awskey     = "XXXX",
    awssecret  = "XXXX";

var stringToSign ='GET\n\n\n' + date + '\n\n' + resource;

var sig = encodeURIComponent(crypto.createHmac('sha1', awssecret).update(stringToSign ).digest('base64'));

var url = "https://s3-eu-west-1.amazonaws.com/mybucket" +
       resource + "?AWSAccessKeyId=" + awskey + "&Expires="+ date +  
      "&Signature="+ sig
Run Code Online (Sandbox Code Playgroud)

这会创建一个类似于此的URL:

https://s3-eu-west-1.amazonaws.com/mybucket/test.txt?AWSAccessKeyId=XXXXXX&Expires=1331290899&Signature=EciGxdQ1uOqgFDCRon4vPqTiCLc%3D
Run Code Online (Sandbox Code Playgroud)

但是,访问它时收到以下错误:

SignatureDoesNotMatch

The request signature we calculated does not match the signature you provided. 
Check your key and signing method.
Run Code Online (Sandbox Code Playgroud)

创建签名时我做错了什么?

编辑 - 与诺克斯一起尝试

我现在正在尝试使用Knox生成签名的URL.我需要添加带有强制下载请求的标头.我编辑了以下内容:

添加amazonHeaders: 'response-content-disposition:attachment',到client.signedUrl- http://jsfiddle.net/BpGNM/1/

添加options.amazonHeaders + '\n' +auth.queryStringToSign- http://jsfiddle.net/6b8Tm/

现在发送auth.hmacSha1给创建sig的消息是:

'GET\n\n\n1321374212\nresponse-content-disposition:attachment\n/meshmesh-dev/test/Readme.md'
Run Code Online (Sandbox Code Playgroud)

然后我尝试使用response-content-disposition=attachment添加的GET var 来访问我的新URL .但是,我仍然收到上述相同的错误.

Sha*_*ali 8

我会尝试使用Knox和Node.Js.它已知是一个伟大的组合,也本身利用Node.JS加密库,这是你正在尝试做的一种 - 节省你的时间:)

更多信息:https://github.com/LearnBoost/knox

比,你可以做一些像:

var knox = require('knox');
var s3Client = knox.createClient({
    key: 'XXX',
    secret: 'XXX',
    bucket: 'XXX'
});

var expires = new Date();
expires.setMinutes(expires.getMinutes() + 30);
var url =  s3Client.signedUrl(filename, expires);
Run Code Online (Sandbox Code Playgroud)

编辑: 您也可以查看Knox并查看signedUrl函数的功能并自行实现.您可以在auth.signQuery调用中添加一个名为的额外选项amazonHeaders:

Client.prototype.signedUrl = function(filename, expiration){
  var epoch = Math.floor(expiration.getTime()/1000);
  var signature = auth.signQuery({
    amazonHeaders: 'response-content-disposition:attachment',
    secret: this.secret,
    date: epoch,
    resource: '/' + this.bucket + url.parse(filename).pathname
  });

  return this.url(filename) +
    '?Expires=' + epoch +
    '&AWSAccessKeyId=' + this.key +
    '&Signature=' + encodeURIComponent(signature);
};
Run Code Online (Sandbox Code Playgroud)

夏嘉曦.