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

PhpStorm .http文件中AWS请求签名失败问题求助

解决PhpStorm .http文件中AWS请求签名不匹配问题

常见错误排查与脚本修正

1. 密钥生成逻辑错误(最可能原因)

AWS4-HMAC-SHA256签名链要求每一步的HMAC输入为二进制哈希结果,而非Hex字符串。你的脚本中每一步都将哈希结果转成Hex,再作为文本密钥传递,这会导致签名计算错误。

修改密钥生成部分:

// 生成密钥时保留二进制 digest,不转Hex
const kDate = crypto.hmac.sha256()
    .withTextSecret("AWS4" + request.environment.get("AWSSecretKey"))
    .updateWithText(eightDigitDate)
    .digest(); // 移除toHex()

const kRegion = crypto.hmac.sha256()
    .withSecret(kDate) // 使用withSecret传递二进制密钥
    .updateWithText(region)
    .digest();

const kService = crypto.hmac.sha256()
    .withSecret(kRegion)
    .updateWithText(service)
    .digest();

const kSigning = crypto.hmac.sha256()
    .withSecret(kService)
    .updateWithText("aws4_request")
    .digest();

// 最终签名时再转Hex
const signature = crypto.hmac.sha256()
    .withSecret(kSigning)
    .updateWithText(StringToSign)
    .digest().toHex();

2. 请求体哈希验证

  • 确认request.body.tryGetSubstituted()获取的是最终发送的请求体内容(包括环境变量替换后的结果),如果是格式化的JSON,要确保和实际发送的内容完全一致(比如空格、换行符)。
  • 空请求体需使用空字符串的SHA256哈希:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855,可手动计算对比脚本输出。

3. Host头严格匹配

AWS签名对Host头的大小写、内容要求严格:

  • 若使用API网关默认域名(如xxxx.execute-api.eu-west-2.amazonaws.com),需确保CanonicalHeaders中的host值与请求的Host完全一致,不能使用自定义域名(除非已配置域名映射并验证)。
  • 不能有多余空格或大小写错误,必须全小写。

4. 日期格式验证

确认dateTimeInAmazonsFormat格式为YYYYMMDD'T'HHMMSS'Z'(如20240520T123456Z),可通过console.log(dateTimeInAmazonsFormat)输出验证。

轻量JS签名实现参考

由于PhpStorm .http文件无法导入外部库,可参考以下简化版AWS签名逻辑(可直接嵌入脚本):
核心逻辑与AWS官方规范一致,仅保留签名必需的步骤:

function signAWSRequest(request, accessKey, secretKey, region, service) {
    const date = new Date();
    const amzDate = date.toISOString().replace(/[:-]/g, '').replace(/\.\d+/, '') + 'Z';
    const dateStamp = amzDate.substr(0, 8);

    // 构建规范请求
    const method = request.method;
    const canonicalUri = request.path;
    const canonicalQueryString = ''; // 无查询参数时为空
    const canonicalHeaders = `content-type:application/json\nhost:${request.host}\nx-amz-date:${amzDate}\n`;
    const signedHeaders = 'content-type;host;x-amz-date';
    const payloadHash = crypto.sha256().updateWithText(request.body.tryGetSubstituted()).digest().toHex();

    const canonicalRequest = `${method}\n${canonicalUri}\n${canonicalQueryString}\n${canonicalHeaders}\n${signedHeaders}\n${payloadHash}`;
    const hashedCanonicalRequest = crypto.sha256().updateWithText(canonicalRequest).digest().toHex();

    // 构建待签名字符串
    const stringToSign = `AWS4-HMAC-SHA256\n${amzDate}\n${dateStamp}/${region}/${service}/aws4_request\n${hashedCanonicalRequest}`;

    // 生成签名密钥链(二进制)
    const kDate = crypto.hmac.sha256().withTextSecret(`AWS4${secretKey}`).updateWithText(dateStamp).digest();
    const kRegion = crypto.hmac.sha256().withSecret(kDate).updateWithText(region).digest();
    const kService = crypto.hmac.sha256().withSecret(kRegion).updateWithText(service).digest();
    const kSigning = crypto.hmac.sha256().withSecret(kService).updateWithText('aws4_request').digest();

    // 生成最终签名
    const signature = crypto.hmac.sha256().withSecret(kSigning).updateWithText(stringToSign).digest().toHex();

    // 构建Authorization头
    const authHeader = `AWS4-HMAC-SHA256 Credential=${accessKey}/${dateStamp}/${region}/${service}/aws4_request, SignedHeaders=${signedHeaders}, Signature=${signature}`;
    
    request.variables.set('XAmzDate', amzDate);
    request.variables.set('Authorization', authHeader);
}

// 调用示例
signAWSRequest(
    request,
    request.environment.get('AWSAccessKey'),
    request.environment.get('AWSSecretKey'),
    'eu-west-2',
    'execute-api'
);

调试技巧

  • 使用console.log()输出CanonicalRequest、StringToSign、signature等关键值,手动对比AWS官方签名示例(或用AWS CLI的aws sigv4 sign命令生成正确签名)。
  • 验证环境变量AWSAccessKey和AWSSecretKey无多余空格或换行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 14:07:04