如何在启用ObjectLock的S3桶的Step Function中正确使用ContentMD5
问题分析与解决方案
你的Step Function定义存在两个关键问题,导致S3返回Content-MD5无效的错误:
- 重复的
Resource字段:定义里出现了两次"Resource": "arn:aws:states:::aws-sdk:s3:putObject",属于语法错误,需要删除其中一个。 - ContentMD5计算逻辑错误:
States.Hash('test data', 'MD5')会对**JSON序列化后的字符串(带双引号的"test data")**计算哈希,而非原始内容test data的字节。- 直接将十六进制哈希值做Base64编码,不符合S3要求——S3需要的是MD5哈希二进制数据的Base64编码,而非十六进制字符串的Base64编码。
修正后的Step Function定义
动态计算ContentMD5(适用于静态/动态Body)
如果你的Step Functions环境支持States.Binary函数(当前大多数AWS区域都支持),可以用以下动态计算逻辑:
{ "Comment": "PutObject to S3 with ObjectLock", "StartAt": "PutObject", "States": { "PutObject": { "Type": "Task", "End": true, "Parameters": { "Body": "test data", "Bucket": "worm-bucket-test", "Key": "logs.txt", "ContentMD5": "States.Base64Encode(States.Binary(States.Hash(States.Base64Decode('dGVzdCBkYXRh'), 'MD5'), 'hex'))" }, "Resource": "arn:aws:states:::aws-sdk:s3:putObject", "Catch": [ { "ErrorEquals": ["States.TaskFailed"], "Next": "Wait1Sec" } ] }, "Wait1Sec": { "Type": "Wait", "Seconds": 1, "Next": "PutObject" } } }
计算逻辑说明:
States.Base64Decode('dGVzdCBkYXRh'):将test data的Base64编码转换为二进制数据,避免JSON序列化时添加的引号,确保哈希基于原始内容字节。States.Hash(..., 'MD5'):计算二进制数据的MD5哈希,返回十六进制字符串。States.Binary(..., 'hex'):将十六进制哈希转换为16字节的二进制MD5值。States.Base64Encode(...):将二进制MD5值编码为S3要求的Base64格式。
静态硬编码ContentMD5(仅适用于固定Body)
如果Body是固定的test data,可以直接提前计算好正确的ContentMD5值硬编码,避免动态计算的复杂性:
"ContentMD5": "nhB9nTc7u4Jt2B01QqQZ1g=="
内容的提问来源于stack exchange,提问作者SirCharles
相关产品推荐
相关产品推荐

