Google App Script对接S3时AWS Signature V4规范请求哈希不匹配问题
解决Google App Script中AWS S3签名V4哈希不匹配问题
核心排查方向与修复方案
1. 规范请求字符串的换行符必须统一为Unix格式
AWS要求规范请求(Canonical Request)中的所有换行必须是\n(Unix风格),如果你的字符串中混入了\r\n(Windows风格),会直接导致哈希计算结果完全偏离。
- 构造Canonical Request时,强制用
\n拼接所有部分,示例:const CanonicalRequest = [ 'PUT', '/google-sheets-to-s3/Test_171RLxS8MIlbge87d97jhelAawuadxQ3stAeYMrDdb-4/Test_0.json', '', // 空查询字符串 'content-type:application/json', 'host:s3.ap-southeast-2.amazonaws.com', 'x-amz-content-sha256:e62b1de6ef3840adb4dae65f5412d15202ddc241c6ba39e5b73dd51ae5613559', 'x-amz-date:20240508T211604Z', 'x-amz-target:PutObject', '', // 分隔头部与签名字段的空行 'content-type;host;x-amz-content-sha256;x-amz-date;x-amz-target', 'e62b1de6ef3840adb4dae65f5412d15202ddc241c6ba39e5b73dd51ae5613559' ].join('\n');
2. 确保x-amz-content-sha256与请求体哈希完全一致
你指定的x-amz-content-sha256值必须是上传文件(Test_0.json)内容的SHA256哈希。如果请求体内容和计算哈希时的源内容不一致,AWS端生成的哈希会和你本地结果不同:
- 重新计算请求体的SHA256哈希,确认与头字段值完全匹配;
- 上传时避免请求体被意外修改(比如添加额外空格、换行)。
3. 验证CredentialScope格式正确性
CredentialScope必须严格遵循YYYYMMDD/region/service/aws4_request格式,你的场景下应为20240508/ap-southeast-2/s3/aws4_request。格式错误会导致整个签名链失效,间接影响哈希验证逻辑。
4. 明确指定UTF-8编码
Google Apps Script的Utilities.computeDigest默认使用UTF-8,但显式指定编码可避免特殊字符的编码异常:
const byte_array_to_string = (v) => v.map(byte => { return (byte < 0 ? byte + 256 : byte).toString(16).padStart(2, '0'); }).join(''); const SHA256 = (v) => { return byte_array_to_string(Utilities.computeDigest(Utilities.DigestAlgorithm.SHA_256, v, Utilities.Charset.UTF_8)); };
额外验证步骤
- 将本地构造的Canonical Request字符串复制到在线SHA256计算器(确保输入时换行符为
\n),确认哈希值为89aa70c68b8b9f5fc19ebb4e390ff90a654bf638aa2ce4bceb9863753409941d; - 抓包查看实际发送给AWS的请求,确认所有头字段、请求体与本地构造的内容完全一致——App Script可能自动添加
Content-Length等头,若这些头未被包含在Canonical Request的签名字段中,也会引发哈希不匹配。
内容的提问来源于stack exchange,提问作者Morgan Bennet
相关产品推荐
相关产品推荐

