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

Bash脚本上传AWS S3:规范请求哈希与AWS生成值不一致问题

问题:Bash脚本上传AWS S3时签名哈希不匹配(Linux环境适配)

使用场景

需编写纯Bash脚本实现AWS S3文件上传,部署到数百台无法安装AWS CLI、s3cmd等工具的Linux系统,已完成Mac平台的zsh版本,适配Linux时遇到签名验证失败问题。

问题详情

脚本生成的CanonicalRequest与AWS端一致,但计算出的canonical_request_hash和AWS StringToSign中要求的哈希值不匹配,触发AWS报错:

The request signature we calculated does not match the signature you provided. Check your key and signing method.

相关代码片段

# Initial Canoncial Request String
canonical_request="PUT
/$file_name

host:$aws_s3_host.s3.amazonaws.com
x-amz-content-sha256:$file_sha256
x-amz-date:$now_time

host;x-amz-content-sha256;x-amz-date
$file_sha256"

# THE CANONICAL REQUEST ABOVE IS WHAT AWS PRODUCES.
###
# Generate Canonical Request Hash
canonical_request_hash=$(echo -n $canonical_request | openssl dgst -sha256)
###
# THE CANONICAL REQUEST HASH ABOVE IS DIFFERENT THAN WHAT AWS PRODUCES.


# String that will be used to generate AWS Signature
string_to_sign="AWS4-HMAC-SHA256
$now_time
$now_date/$region/s3/aws4_request
$canonical_request_hash"

已尝试方案

  • 替换哈希计算命令:sha256sum、openssl dgst -sha256
  • 调整echo的-n参数(添加/移除)
  • 将canonical_request写入文件后再哈希文件

解决办法

问题出在两个关键细节:

1. 变量引用丢失换行符

Bash中直接使用echo -n $canonical_request时,变量内的换行符会被替换为空格,导致实际哈希的内容和原始CanonicalRequest不一致。必须用双引号包裹变量,并使用printf替代echo保证跨平台可靠性:

printf "%s" "$canonical_request"

2. Linux下openssl输出带前缀

Linux环境中openssl dgst -sha256的输出会包含SHA256(stdin)= 前缀,而AWS需要的是纯哈希值,需提取哈希部分。

结合两点,修改后的哈希计算代码:

# 用printf输出原始CanonicalRequest,提取openssl输出的纯哈希值
canonical_request_hash=$(printf "%s" "$canonical_request" | openssl dgst -sha256 | awk '{print $2}')

如果使用sha256sum,同样需要提取纯哈希:

canonical_request_hash=$(printf "%s" "$canonical_request" | sha256sum | awk '{print $1}')

修改后重新运行脚本,canonical_request_hash将和AWS要求的一致,签名验证即可通过。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 10:40:58