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

使用Curl上传数据至AWS S3出错,求解决方法及示例代码

解决Curl上传AWS S3的签名及加密问题

核心问题分析

你的脚本使用的是AWS Signature Version 2(SigV2),但目前AWS S3绝大多数区域已不再支持SigV2,强制要求使用Signature Version 4(SigV4),这是请求失败的主要原因。另外如果你的S3桶启用了KMS默认加密,还需要在请求中添加对应的加密头。

修正方案及示例代码

以下是适配SigV4且支持KMS加密的完整Shell脚本:

#!/usr/bin/env bash
set -eo pipefail

# 配置参数
file_to_upload="/home/sraj/Hello10.txt"
bucket="mybucket"
# S3对象键:仅填桶内路径/文件名,不要带桶名或本地绝对路径
object_key="Hello10.txt"
# 若桶启用KMS默认加密,填写KMS密钥ARN/别名;无需加密则注释此行
kms_key_id="arn:aws:kms:us-east-1:123456789012:key/xxxxxx"
content_type="application/x-compressed-tar"
region="us-east-1" # 替换为你的桶所在AWS区域

# 生成SigV4要求的UTC时间格式
date_now=$(date -u +"%Y%m%d")
datetime_now=$(date -u +"%Y%m%dT%H%M%SZ")

# 构建规范请求(SigV4核心步骤)
canonical_request="PUT
/${object_key}

content-type:${content_type}
host:${bucket}.s3.${region}.amazonaws.com
x-amz-date:${datetime_now}
x-amz-server-side-encryption:aws:kms
x-amz-server-side-encryption-aws-kms-key-id:${kms_key_id}

content-type;host;x-amz-date;x-amz-server-side-encryption;x-amz-server-side-encryption-aws-kms-key-id
$(openssl dgst -sha256 -binary "${file_to_upload}" | base64)"

# 构建待签字符串
string_to_sign="AWS4-HMAC-SHA256
${datetime_now}
${date_now}/${region}/s3/aws4_request
$(echo -n "${canonical_request}" | openssl dgst -sha256 -hex | awk '{print $2}')"

# 生成SigV4签名密钥
signing_key=$(echo -n "AWS4${s3_secret_key}" | openssl dgst -sha256 -hmac "${date_now}" -binary | openssl dgst -sha256 -hmac "${region}" -binary | openssl dgst -sha256 -hmac "s3" -binary | openssl dgst -sha256 -hmac "aws4_request" -binary)
signature=$(echo -n "${string_to_sign}" | openssl dgst -sha256 -hmac "${signing_key}" -binary | base64)

# 执行Curl上传请求
curl -X PUT -T "${file_to_upload}" \
  -H "Content-Type: ${content_type}" \
  -H "Host: ${bucket}.s3.${region}.amazonaws.com" \
  -H "X-Amz-Date: ${datetime_now}" \
  -H "X-Amz-Server-Side-Encryption: aws:kms" \
  -H "X-Amz-Server-Side-Encryption-AWS-KMS-Key-Id: ${kms_key_id}" \
  -H "Authorization: AWS4-HMAC-SHA256 Credential=${s3_access_key}/${date_now}/${region}/s3/aws4_request, SignedHeaders=content-type;host;x-amz-date;x-amz-server-side-encryption;x-amz-server-side-encryption-aws-kms-key-id, Signature=${signature}" \
  "https://${bucket}.s3.${region}.amazonaws.com/${object_key}"

关键修正点说明

  • 切换至SigV4签名:完全重写了签名生成逻辑,符合AWS当前唯一支持的SigV4规范,解决了旧版本签名的兼容性问题。
  • KMS加密适配:若桶启用SSE-KMS默认加密,必须添加X-Amz-Server-Side-Encryption系列头;无需加密则直接删除相关代码块。
  • 路径修正:原脚本错误地将本地绝对路径作为S3对象键,修正为仅包含桶内的目标路径/文件名。
  • 区域指定:SigV4要求明确指定桶所在的AWS区域,需替换为你的实际区域(如us-west-2、eu-central-1)。
  • 时间格式:使用UTC标准时间格式,避免时区差异导致的签名验证失败。

额外注意事项

  1. 确保IAM用户拥有s3:PutObject权限;若使用KMS,还需拥有对应密钥的kms:GenerateDataKey和kms:Decrypt权限。
  2. 不要硬编码密钥到脚本中,建议通过环境变量传递(如export AWS_ACCESS_KEY_ID=xxx、export AWS_SECRET_ACCESS_KEY=yyy)。
  3. 若无需服务器端加密,删除所有与KMS相关的头和变量即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 06:46:07