S3上传文件完整性校验触发Content-MD5 BadDigest报错咨询
S3上传Content-MD5校验报错BadDigest的解决方案
常见疏漏点
- 最容易忽略的核心问题:
aws s3api put-object命令未指定--body参数,你当前的命令没有声明要上传的本地文件路径,S3实际接收的是空对象,和你计算校验值的文件内容完全不一致,必然报错。 - openssl md5命令输出带额外前缀:部分版本的openssl执行md5计算时会输出
MD5(文件名)=的前缀,直接管道给base64编码时会把前缀内容一起计算,导致最终校验值错误。 - base64输出包含换行符:默认base64命令会在输出超过76字符时自动换行,或者末尾带换行符,复制使用时带入不可见换行字符会导致校验值不匹配。
- 非二进制MD5值编码错误:不加
-binary参数时得到的是MD5的十六进制字符串,S3要求传入的是128位MD5二进制值的base64编码,直接对十六进制字符串编码不符合规范。
正确操作步骤
步骤1:生成符合要求的Content-MD5值
Linux环境执行:
# 方式1:使用md5sum(无额外前缀问题,更稳定) md5sum test-md5.txt | awk '{print $1}' | xxd -r -p | base64 -w 0
macOS环境执行:
# 方式2:使用openssl,过滤前缀并输出无换行base64 openssl md5 -binary test-md5.txt | sed 's/^.*= //' | base64 -A
步骤2:执行带--body参数的上传命令
将上一步生成的校验值替换到下方命令对应位置:
aws s3api put-object --bucket cloudtrailmanual --key test-md5.txt --body test-md5.txt --content-md5 生成的base64校验值
验证方法
上传成功后可执行如下命令验证校验和匹配:
# 本地获取十六进制MD5 LOCAL_MD5=$(md5sum test-md5.txt | awk '{print $1}') # 获取S3返回的ETag(单块非加密上传的ETag等于文件MD5十六进制) S3_ETAG=$(aws s3api head-object --bucket cloudtrailmanual --key test-md5.txt --query ETag --output text | tr -d '"') # 比对两者是否一致 echo $LOCAL_MD5 $S3_ETAG
内容的提问来源于stack exchange,提问作者Gaurav Parashar
相关产品推荐
相关产品推荐

