请求Amazon SQS持续出现SignatureDoesNotMatch错误,寻求排查方案
解决Amazon SQS请求的SignatureDoesNotMatch错误
我正尝试生成以下请求头参数以确保向Amazon SQS的请求成功:
- X-Amz-Content-Sha256
- Authorization
- X-Amz-Date
为添加上述请求头,我用Node.js编写了Postman预请求脚本,但持续收到SignatureDoesNotMatch错误。补充信息:授权类型为AWS Signature,Access Key和Secret Key均正确。
脚本如下:
const crypto = require('crypto-js'); const moment = require('moment'); // Derive signing key function getSignatureKey(key, dateStamp, regionName, serviceName) { var kDate = crypto.HmacSHA256("AWS4"+key, dateStamp); var kRegion = crypto.HmacSHA256(kDate, regionName); var kService = crypto.HmacSHA256(kRegion, serviceName); var kSigning = crypto.HmacSHA256(kService, "aws4_request"); return kSigning; } var access_key = "AccessKey"; var secret_key = "SecretKey"; var method = 'POST'; var service = 'sqs'; var host = "sqs-endpoint"; var region = "Region-east"; var content_type = 'application/x-www-form-urlencoded'; // Construct the canonical URI var canonical_uri = '/<<sqs_queue_name>>'; // SQS queue name // Create a date for headers and the credential string var amz_date = moment().utc().format("YYYYMMDD[T]HHmmss[Z]"); // Date in ISO8601 basic format with only date (no time) var date_stamp = moment().utc().format("YYYYMMDD"); var canonical_querystring = ''; // Covert the hash to a hexadecimal string var payload = req.getBody(); var payload_hash = crypto.SHA256(payload).toString(crypto.enc.Hex); // Sample Payload looks like below: // { // "id": "ACDBJHDDL", // "name": "xyz", // "Type": "function", // "Number": "12345", // "user":"ASPD", // "requesteduser":"ASPD" // } // Construct the canonical headers canonical_headers = 'content-type:' + content_type + '\n' + 'host:'+ host + '\n' + 'x-amz-content-sha256:' + payload_hash + '\n' + 'x-amz-date:' + amz_date + '\n'; // Construct the signed headers var signed_headers = 'content-type;host;x-amz-content-sha256;x-amz-date'; // Construct the canonical request & hash var canonical_request = method + '\n' + canonical_uri + '\n' + canonical_querystring + '\n' + canonical_headers + '\n' + signed_headers + '\n' + payload_hash; var hex_canonical_request = crypto.SHA256(canonical_request).toString(crypto.enc.Hex); // Construct the string to sign var algorithm = 'AWS4-HMAC-SHA256 '; var credential_scope = date_stamp+'/'+region+'/'+service+'/'+'aws4_request'; var string_to_sign = algorithm + '\n' + amz_date + '\n' + credential_scope + '\n' + hex_canonical_request; // Create the signing key using the function getSignatureKey defined above. var signing_key = getSignatureKey(secret_key, date_stamp, region, service); //Sign the string_to_sign using the signing_key //Calculate the signature //Covert the hash to a hexadecimal string and calculate the signature var signature = crypto.HmacSHA256(signing_key, string_to_sign).toString(crypto.enc.Hex); // Construct the authorization header var authorization_header = algorithm + 'Credential=' + access_key + '/' + credential_scope + ', ' + 'SignedHeaders=' + signed_headers + ', ' + 'Signature=' + signature; // Setting the header to send with the request req.setHeader("Authorization", authorization_header); req.setHeader("X-Amz-Content-Sha256", payload_hash); req.setHeader("X-Amz-Date", amz_date); req.setHeader("Host", host);
我已按照AWS官方文档编写脚本,但问题仍存在,请求帮助排查。
问题排查与修正方案
1. HMAC参数顺序错误
CryptoJS的HmacSHA256方法参数顺序为**(消息, 密钥)**,你的脚本中完全写反了,这是签名不匹配的核心原因。修正后的签名密钥生成函数:
function getSignatureKey(key, dateStamp, regionName, serviceName) { var kDate = crypto.HmacSHA256(dateStamp, "AWS4"+key); var kRegion = crypto.HmacSHA256(regionName, kDate); var kService = crypto.HmacSHA256(serviceName, kRegion); var kSigning = crypto.HmacSHA256("aws4_request", kService); return kSigning; }
2. Content-Type与Payload不匹配
你的示例Payload是JSON格式,但content_type设置为application/x-www-form-urlencoded,这会导致AWS计算的Payload哈希与你生成的不一致。如果发送JSON,需修改:
var content_type = 'application/json';
3. Canonical URI格式错误
SQS的标准Canonical URI需包含账号ID,格式为/123456789012/queue-name,而非单纯的/queue-name,需替换为你队列的完整路径。
4. Region格式错误
AWS Region采用标准格式(如us-east-1),你的"Region-east"不符合规范,需修改为正确的Region名称。
5. 签名计算参数顺序错误
最后一步生成签名时,HmacSHA256的参数同样写反,修正:
var signature = crypto.HmacSHA256(string_to_sign, signing_key).toString(crypto.enc.Hex);
6. Authorization头算法字符串多余空格
algorithm = 'AWS4-HMAC-SHA256 '末尾的空格会导致头格式错误,需删除:
var algorithm = 'AWS4-HMAC-SHA256';
内容的提问来源于stack exchange,提问作者Sweety
相关产品推荐
相关产品推荐

