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

使用带强制Content-MD5的AWS S3预签名URL上传失败排查

问题排查:AWS S3预签名URL带Content-MD5校验上传失败的原因

我来帮你搞定这个问题——你踩了一个非常常见的MD5编码误区!

核心错误点

你从md5命令拿到的是十六进制字符串格式的MD5哈希值,但AWS S3要求的Content-MD5请求头,必须是原始MD5二进制哈希值的Base64编码结果,而不是把十六进制字符串直接转成Base64。

你的代码里做了base64.StdEncoding.EncodeToString([]byte(md5)),这相当于把"ce0a4a83c88c2e7562968f03076ae62f"这个纯文本字符串转成了Base64,完全不符合AWS的要求,所以会返回InvalidDigest错误。

修正方案

你需要先把十六进制的MD5字符串解码成原始二进制字节,再对这些字节做Base64编码。修改代码里的MD5处理部分(记得补充encoding/hex包的导入):

import (
    "encoding/base64"
    "encoding/hex"
    "fmt"
    "time"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/s3"
)

func main() {
    sess, err := session.NewSession(&aws.Config{
        Region: aws.String("eu-central-1")},
    )
    if err != nil {
        fmt.Println("error creating session", err)
        return
    }
    svc := s3.New(sess)

    resp, err := svc.PutObjectRequest(&s3.PutObjectInput{
        Bucket: aws.String("bucket"),
        Key:    aws.String("testfile.txt"),
    })
    if err != nil {
        fmt.Println("error creating put request", err)
        return
    }

    md5Hex := "ce0a4a83c88c2e7562968f03076ae62f"
    // 第一步:把十六进制字符串解码为原始二进制MD5值
    md5Bytes, err := hex.DecodeString(md5Hex)
    if err != nil {
        fmt.Println("error decoding MD5 hex string", err)
        return
    }
    // 第二步:对二进制值做Base64编码,得到AWS要求的Content-MD5
    md5Base64 := base64.StdEncoding.EncodeToString(md5Bytes)
    resp.HTTPRequest.Header.Set("Content-MD5", md5Base64)

    url, err := resp.Presign(15 * time.Minute)
    if err != nil {
        fmt.Println("error presigning request", err)
        return
    }

    fmt.Printf("curl -XPUT -H \"Content-MD5: %s\" %s --upload-file %s\n\n", md5Base64, url, "testfile.txt")
}

额外验证技巧

你可以用openssl命令提前生成正确的Base64编码MD5,和代码输出对比,确保编码正确:

openssl md5 -binary testfile.txt | base64

这个命令的输出应该和代码里的md5Base64完全一致。

关于签名不匹配的补充说明

当你直接用原始十六进制MD5值作为Content-MD5头时,预签名请求会把这个头包含在签名计算里,但实际上传时S3会验证这个头的格式是否符合要求(必须是Base64编码的二进制MD5),同时签名计算的内容和实际请求的有效负载校验不匹配,所以会返回SignatureDoesNotMatch错误。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:53:54