如何构造正确的AWS Secrets Manager API请求签名?
解决方案
AWS的AWS4-HMAC-SHA256签名不是直接对整个HTTP payload做哈希,而是要按照固定的签名流程分步计算,这也是你用在线工具直接哈希payload无法匹配的原因。以下是正确的构造和签名步骤:
1. 明确签名核心要素
签名依赖以下几个不可出错的参数:
- 你的AWS Access Key ID和Secret Access Key
- 请求的
X-Amz-Date(格式必须是YYYYMMDD'T'HHMMSS'Z',和请求时间严格对应) - 目标区域(这里是
eu-central-1) - 服务名称(这里是
secretsmanager) - 请求的规范请求(Canonical Request)
2. 构造规范请求(Canonical Request)
这是签名的核心基础,必须严格按以下格式拼接:
HTTP_METHOD CANONICAL_URI CANONICAL_QUERY_STRING CANONICAL_HEADERS SIGNED_HEADERS PAYLOAD_HASH
对应你的请求:
- HTTP_METHOD:
POST - CANONICAL_URI:
/(请求路径为根) - CANONICAL_QUERY_STRING:空字符串(无查询参数)
- CANONICAL_HEADERS:将所有签名header按小写字母排序,每个header后加换行,格式为
header-name:header-value\n,值不能有多余空格:accept-encoding:identity content-type:application/x-amz-json-1.1 host:secretsmanager.eu-central-1.amazonaws.com x-amz-content-sha256:beaead3198f7da1e70d03ab969765e0821b24fc913697e929e726aeaebf0eba3 x-amz-date:20220809T093728Z x-amz-target:secretsmanager.GetSecretValue - SIGNED_HEADERS:即
Authorization头里的signedheaders值,按相同顺序拼接:accept-encoding;content-type;host;x-amz-content-sha256;x-amz-date;x-amz-target - PAYLOAD_HASH:即
X-Amz-Content-Sha256的值,是请求body的SHA256哈希(body必须和请求发送的完全一致,包括换行、空格)
将以上内容拼接成字符串后,对整个字符串做SHA256哈希,得到HASHED_CANONICAL_REQUEST。
3. 构造待签名字符串(String to Sign)
格式如下:
AWS4-HMAC-SHA256 X_AMZ_DATE DATE_REGION_SERVICE HASHED_CANONICAL_REQUEST
对应你的请求:
- 第一行固定为
AWS4-HMAC-SHA256 - X_AMZ_DATE:请求里的
X-Amz-Date值:20220809T093728Z - DATE_REGION_SERVICE:由日期(取X-Amz-Date的前8位)、区域、服务、固定后缀组成:
20220809/eu-central-1/secretsmanager/aws4_request - HASHED_CANONICAL_REQUEST:上一步得到的哈希值
4. 计算签名密钥(Signing Key)
用你的AWS Secret Access Key按以下步骤分层做HMAC-SHA256加密:
kDate = HMAC-SHA256("AWS4" + SECRET_ACCESS_KEY, "20220809") kRegion = HMAC-SHA256(kDate, "eu-central-1") kService = HMAC-SHA256(kRegion, "secretsmanager") kSigning = HMAC-SHA256(kService, "aws4_request")
这里的日期必须和X-Amz-Date的前8位一致。
5. 生成最终签名
用得到的kSigning密钥对第三步的待签名字符串做HMAC-SHA256加密,再转成十六进制字符串,就是Authorization头里的Signature值。
6. 用cURL构造请求
把以上步骤计算出的X-Amz-Date、X-Amz-Content-Sha256、Authorization头填入cURL命令,注意body要和计算payload哈希时完全一致:
curl -X POST https://secretsmanager.eu-central-1.amazonaws.com/ \ -H "Content-Type: application/x-amz-json-1.1" \ -H "X-Amz-Target: secretsmanager.GetSecretValue" \ -H "Accept-Encoding: identity" \ -H "X-Amz-Content-Sha256: beaead3198f7da1e70d03ab969765e0821b24fc913697e929e726aeaebf0eba3" \ -H "X-Amz-Date: 20220809T093728Z" \ -H "Authorization: AWS4-HMAC-SHA256 Credential=YOUR_ACCESS_KEY/20220809/eu-central-1/secretsmanager/aws4_request, SignedHeaders=accept-encoding;content-type;host;x-amz-content-sha256;x-amz-date;x-amz-target, Signature=YOUR_CALCULATED_SIGNATURE" \ -d '{ "SecretId": "arn:aws:secretsmanager:eu-central-1:rest-of-arn" }'
关键注意事项
- 所有步骤的字符串拼接不能有多余的空格或换行,尤其是规范请求的每个部分必须严格对应
X-Amz-Date必须和签名计算时用的日期完全一致,每次请求时间变化,签名必须重新计算- 不要用在线工具直接哈希整个payload,必须按AWS的四步签名流程计算
- 如果嫌手动计算麻烦,可以用AWS CLI的
aws secretsmanager get-secret-value命令,或者用AWS SDK(比如Python的boto3),会自动处理签名
内容的提问来源于stack exchange,提问作者menash
相关产品推荐
相关产品推荐

