Python生成AWS S3签名遇AttributeError:HMAC实例无__len__属性
解决Python2.7中S3签名时的AttributeError: HMAC instance has no attribute 'len'
这个错误我之前在Python2.7里搞AWS S3 v4签名时也踩过坑,核心原因是你把hmac.new()返回的HMAC实例直接当作了下一个HMAC计算的key参数,但Python2.7的hmac模块要求key必须是可计算长度的字符串/字节串,而HMAC实例本身没有__len__属性,所以触发了这个错误。
错误根源分析
看你提到的代码片段:
datekey = hmac.new(str("AWS4") + AWS_UPLOAD_SECRET_KEY, stringdate...)
这里hmac.new()返回的是一个HMAC类的实例,而不是签名后的二进制结果。如果你后续把这个datekey直接作为参数传入下一个hmac.new(),就会出现那个属性错误。
修复步骤(符合AWS S3 v4签名流程)
AWS S3的v4签名需要分层计算密钥,每一步都要获取HMAC的二进制签名结果(通过.digest()方法),才能作为下一层的密钥:
计算Date Key
# 确保所有输入都是字节串(Python2.7中str默认是,但unicode需encode) date_key = hmac.new( ("AWS4" + AWS_UPLOAD_SECRET_KEY).encode('utf-8'), stringdate.encode('utf-8'), hashlib.sha256 ).digest() # 关键:调用digest()获取二进制结果计算Region Key
region_key = hmac.new( date_key, AWS_REGION.encode('utf-8'), hashlib.sha256 ).digest()计算Service Key
# S3的服务名称是's3' service_key = hmac.new( region_key, 's3'.encode('utf-8'), hashlib.sha256 ).digest()计算最终的Signing Key
signing_key = hmac.new( service_key, 'aws4_request'.encode('utf-8'), hashlib.sha256 ).digest()计算最终签名
现在用正确的signing_key(二进制结果)去计算policy的签名:# 如果需要十六进制格式的签名(S3通常要求这个),用hexdigest() signature = hmac.new(signing_key, policy.encode('utf-8'), hashlib.sha256).hexdigest()
额外注意事项
- 确保所有传入
hmac.new()的字符串都正确编码为UTF-8字节串(Python2.7中如果是unicode类型,必须调用.encode('utf-8')转成str) - 如果你需要的是二进制签名,用
.digest();如果是十六进制字符串签名(S3 API常用),用.hexdigest() - 检查你的
policy是否是正确的Base64编码后的JSON字符串(S3签名要求对Base64编码后的policy进行HMAC计算)
内容的提问来源于stack exchange,提问作者user9487981
相关产品推荐
相关产品推荐

