You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用JavaScript调用AWS S3 REST API遇SignatureDoesNotMatch错误求助

AWS S3 SignatureDoesNotMatch 错误排查

我用Node.js编写了通过REST API发送GET请求的代码,使用Access Key和Secret Key生成签名,但遇到了SignatureDoesNotMatch错误。相同的请求头在Postman中可以正常运行,以下是我的代码及错误信息,恳请帮忙定位问题:

var https = require('https');
var crypto = require('crypto');

function sign(key, message) {
  return crypto.createHmac('sha256', key).update(message).digest();
}

function getSignatureKey(key, dateStamp, regionName, serviceName) {
  kDate = sign('AWS4' + key, dateStamp);
  kRegion = sign(kDate, regionName);
  kService = sign(kRegion, serviceName);
  kSigning = sign(kService, 'aws4_request');
  return kSigning;
}

// values retrieved from Cognito Federation
accessKey = "MYACCESSKEY";
secretKey = "my/sharedkey";

region = "us-east-1";
serviceName = "s3";

// ex 20180518T210317Z
var now = new Date();
amzdate = now.toJSON().replace(/[-:]/g, "").replace(/\.[0-9]*/, "");
datestamp = now.toJSON().replace(/-/g, "").replace(/T.*/, "");

// prepare to send an HTTP request to https://your-api-gateway.execute-api.eu-west-2.amazonaws.com/stage/secure/endpoint
apiMethod = "GET";
apiHost = "my_host_name.com";
apiEndpoint="/bucket_name/object_name";

apiQueryString = "";
canonicalHeaders = "host:" + apiHost + "\nx-amz-date:" + amzdate +"\n";
  //"\nx-amz-security-token:" + sessionToken + "\n"
signedHeaders = "host;x-amz-date;";
payloadHash = crypto.createHash('sha256').update('').digest('hex');
canonicalRequest = apiMethod + "\n" + apiEndpoint + "\n" + apiQueryString +
  "\n" + canonicalHeaders + "\n" + signedHeaders + "\n" + payloadHash;
console.log('preparing to invoke canonical request:');
console.log(canonicalRequest);

// ************* TASK 2: CREATE THE STRING TO SIGN*************
// Match the algorithm to the hashing algorithm you use, either SHA-1 or
// SHA-256 (recommended)
algorithm = 'AWS4-HMAC-SHA256';
credentialScope = datestamp + '/' + region + '/' + serviceName + '/' +
  'aws4_request';
stringToSign = algorithm + '\n' + amzdate + '\n' + credentialScope + '\n' +
  crypto.createHash('sha256').update(canonicalRequest).digest('hex');

// ************* TASK 3: CALCULATE THE SIGNATURE *************
// Create the signing key using the function defined above.
signingKey = getSignatureKey(secretKey, datestamp, region, serviceName);
// Sign the string_to_sign using the signing_key
signature = crypto.createHmac('sha256', signingKey).update(stringToSign).digest(
  'hex');


// ************* TASK 4: ADD SIGNING INFORMATION TO THE REQUEST *************
// The signing information can be either in a query string value or in
// a header named Authorization. This code shows how to use a header.
// Create authorization header and add to request headers
authorizationHeader = algorithm + ' ' + 'Credential=' + accessKey + '/' +
  credentialScope + ', ' + 'SignedHeaders=' + signedHeaders + ', ' +
  'Signature=' + signature;

  process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0

var options = {
  method: apiMethod,
  host: apiHost,
  path: apiEndpoint,
  headers: {
    'X-Amz-Date': amzdate,
    'Authorization': authorizationHeader
  }
};

callback = function(response) {
  var str = '';

  //another chunk of data has been recieved, so append it to `str`
  response.on('data', function(chunk) {
    str += chunk;
  });
  console.log("CALLBACK",str);

  //the whole response has been recieved, so we just print it out here
  response.on('end', function() {
    console.log('Complete: ' + str);
  });
}
console.log(options);
https.request(options, callback).end();

错误信息:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Error>
    <Code>SignatureDoesNotMatch</Code>
    <Resource>archivestorage/objectNameNotDecodedYet</Resource>
    <Message>The request signature we calculated does not match the signature you provided. Check your secret access key and signing method.</Message>
</Error>

排查关键点

  • 签名头格式错误:signedHeaders末尾多了分号,AWS要求签名头列表不能以分号结尾,应改为"host;x-amz-date"。
  • 路径未编码:S3要求路径中的特殊字符必须做URI编码(比如空格、中文、特殊符号),Postman会自动处理,但代码中直接使用原始路径会导致签名不匹配,需对apiEndpoint中的特殊字符进行编码。
  • Secret Key处理:确保secretKey原样使用,若包含斜杠等特殊字符,不要进行转义或修改。
  • 时间同步问题:AWS签名对时间精度要求高,本地时间与UTC时间差不能超过5分钟,检查amzdate和datestamp生成是否正确,建议使用UTC时间而非本地时间。
  • 规范请求格式:确保canonicalRequest的各部分之间严格用\n分隔,没有多余空格或换行;canonicalHeaders必须以\n结尾,且顺序要与signedHeaders一致。
  • 服务与区域匹配:确认serviceName(s3)和region(us-east-1)与目标S3桶的实际配置完全一致,需和Postman中的参数保持相同。

内容的提问来源于stack exchange,提问作者sourav_anand

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 18:09:26