创建已签名的 AWS API 请求 - AWS 一般参考

创建已签名的 AWS API 请求

下文概述了创建已签名的请求的流程。如需了解更多信息,请参阅 AWS 软件开发工具包中的代码示例

第 1 步:创建规范请求

串联以下由换行符分隔的字符串,以创建规范请求。这有助于确保您计算出的签名与 AWS 计算出的签名相匹配。

HTTPMethod CanonicalUri CanonicalQueryString CanonicalHeaders SignedHeaders HashedPayload
  • HTTPMethod – HTTP 方法。

  • CanonicalUri – 绝对路径组件 URL 的 URI 编码版本(主机和以问号字符(?)开头的查询字符串参数之间的所有内容)。如果绝对路径为空,则使用正斜杠字符(/)。

  • CanonicalQueryString – 用连字符(&)分隔的 URL 编码的查询字符串参数。对预留字符(包括空格字符)进行百分号编码。分别对名称和值进行编码。如果参数为空,请在编码之前在参数名称后面加上等号。编码后,按键名称的字母顺序对参数进行排序。如果没有查询字符串,请使用空字符串 ("")。

  • CanonicalHeaders – 将签署的请求标头及其值,由换行符分隔。标头名称必须使用小写字符,必须按字母顺序显示,必须在后面加上冒号(:)。对于这些值,去除所有前导空格或尾部空格,将连续空格转换为单个空格,并使用逗号分隔多值标头的值。您必须在签名中包含 host 标头(HTTP/1.1)或 :authority 标头(HTTP/2)以及任何 x-amz-* 标头。您可选择在签名中包含其他标准标头,例如 content-type

  • SignedHeaders – 包含在 CanonicalHeaders 中的标头列表,由分号(;)分隔。这表明哪些标头是签名过程的一部分。标头名称必须使用小写字符,必须按字母顺序显示。

  • HashedPayload – 使用 HTTP 请求正文中的负载作为哈希函数的输入创建的字符串。此字符串使用小写十六进制字符。如果有效负载为空,则使用空字符串作为哈希函数的输入。

以下是调用 Amazon EC2 DescribeInstances API 操作的规范请求的示例。

GET / Action=DescribeInstances&Version=2016-11-15 content-type:application/x-www-form-urlencoded; charset=utf-8 host:ec2.amazonaws.com x-amz-date:20220830T123600Z host;x-amz-date payload-hash

第 2 步:创建规范请求的哈希

使用创建负载的哈希时所使用的相同算法来创建规范请求的哈希(摘要)。经过哈希处理的规范请求必须以小写十六进制字符串形式表示。

第 3 步:创建要签名的字符串

串联以下由换行符分隔的字符串,以创建字符串。请勿使用换行符作为此字符串的结尾。

Algorithm RequestDateTime CredentialScope HashedCanonicalRequest
  • Algorithm – 用于创建规范请求的哈希的算法。对于 SHA-256,算法是 AWS4-HMAC-SHA256

  • RequestDateTime – 在凭证范围内使用的日期和时间。

  • CredentialScope – 凭证范围。这会将生成的签名限制在指定的区域和服务范围内。该字符串采用以下格式:YYYYMMDD/region/service/aws4_request。

  • HashedCanonicalRequest – 规范请求的哈希。

以下是要签名的字符串的示例。

AWS4-HMAC-SHA256 20220830T123600Z 20220830/us-east-1/ec2/aws4_request canonical-request-hash

第 4 步:计算签名

创建要签名的字符串后,即可计算要添加至请求的身份验证信息的签名。对于每个步骤,使用所需的密匙和数据调用哈希函数。

hash(key, data)

每次调用哈希函数的结果都会变成下一次调用哈希函数的输入。

必填项
  • 字符串 Key,其中包含您的秘密访问密钥

  • 字符串 Date,其中包含在凭证范围中使用的日期,格式为 YYYYMMDD

  • 字符串 Region,其中包含区域代码(例如,us-east-1

  • 字符串 Service,其中包含服务代码(例如,ec2

  • 在上一步中创建的要签名的字符串。

计算签名
  1. 连接“AWS4”和秘密访问密钥。使用密钥和数据调用哈希函数,并将连接的字符串作为密钥,而日期字符串作为数据。

    kDate = hash("AWS4" + Key, Date)
  2. 使用密钥和数据调用哈希函数,并将上一次调用的结果作为密钥,而区域字符串作为数据。

    kRegion = hash(kDate, Region)
  3. 使用密钥和数据调用哈希函数,并将上一次调用的结果作为密钥,而服务字符串作为数据。

    kService = hash(kRegion, Service)
  4. 使用密钥和数据调用哈希函数,并将上一次调用的结果作为密钥,而“aws4_request”作为数据。

    kSigning = hash(kService, "aws4_request")
  5. 使用密钥和数据调用哈希函数,并将上一次调用的结果作为密钥,而要签名的字符串作为数据。结果是作为二进制值的签名。

    signature = hash(kSigning, string-to-sign)
  6. 将签名从二进制转换为十六进制表示形式,使用小写字符。

第 5 步:将签名添加至请求。

您可使用 HTTP Authorization 标头或查询字符串参数,将身份验证信息添加至请求。您无法同时使用 Authorization 标头和查询字符串参数来添加身份验证信息。

例 示例:授权标头

以下示例显示了 DescribeInstances 操作的 Authorization 标头。为便于阅读,此示例已使用换行符编排过格式。在您的代码中,这必须是连续的字符串。算法和 Credential 之间没有逗号。但是,必须使用逗号分隔其他元素。

Authorization: AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20220830/us-east-1/ec2/aws4_request, SignedHeaders=host;x-amz-date, Signature=calculated-signature
例 示例:请求在查询字符串中使用身份验证参数

以下示例显示了对包含身份验证信息的 DescribeInstances 操作的查询。为便于阅读,此示例已使用换行符编排过格式,而非 URL 编码。在您的代码中,查询字符串必须是采用 URL 编码的连续字符串。

https://ec2.amazonaws.com/? Action=DescribeInstances& Version=2016-11-15& X-Amz-Algorithm=AWS4-HMAC-SHA256& X-Amz-Credential=AKIAIOSFODNN7EXAMPLE/20220830/us-east-1/ec2/aws4_request& X-Amz-Date=20220830T123600Z& X-Amz-SignedHeaders=host;x-amz-date& X-Amz-Signature=calculated-signature

临时安全凭证

您可使用 AWS Security Token Service(AWS STS)提供的临时安全凭证来签署请求,而不是使用长期凭证。

使用临时安全凭证时,必须将 X-Amz-Security-Token 添加至授权标头或查询字符串以保存会话令牌。某些服务会要求您将 X-Amz-Security-Token 添加至规范请求。其他服务仅会要求您在计算出签名后在末尾添加 X-Amz-Security-Token。有关详细信息,请查看每种 AWS 服务 的文档。

AWS 软件开发工具包中的代码示例

AWS 软件开发工具包包括 GitHub 上的源代码,显示了如何签署 AWS API 请求。