签名

签名是对发送到 Cloud Storage XML API 的请求进行身份验证的一种方法。例如,在处理签名网址或 HTML 表单时,系统会使用签名。

概览

签名同时提供了一般性身份验证功能和加强型身份验证功能,从而确保使用特定帐号的权限处理发送到 Cloud Storage 的请求。签名在实现此类身份验证时,不会泄露与该帐号关联的敏感密钥信息(称为“密文”)。

当您发出带有签名的请求时,Cloud Storage 会使用其密文副本来计算该请求的等效签名。如果该请求中包含的签名与 Cloud Storage 计算的签名匹配,则 Cloud Storage 会知道该签名是使用相关的密文创建的。

在 Cloud Storage 中,处理以下信息时,必须使用签名:

此外,在以下情况中,也可以使用签名:

  • 向 XML API 发出直接的签名请求。

从 Amazon S3 执行简单迁移时,在直接请求中使用签名很有用;不过,我们针对直接请求所推荐的身份验证流程是使用 OAuth 2.0 令牌。

结构

创建签名的组成部分和流程取决于签名的用途以及您所使用的身份验证密钥;从广义上来说,签名有两个组成部分:签名密钥和请求信息。您可以对这两个组成部分应用签名算法来创建签名。下表总结了签名的不同使用场景以及在每个场景中构造签名所需的组成部分:

用例 签名密钥 请求信息
带有 RSA 密钥的 HTML 表单 直接使用 RSA 密钥的密文 Base64 编码的政策文档
带有 HMAC 密钥的 HTML 表单 从 HMAC 密钥的密文派生 Base64 编码的政策文档
带有 RSA 密钥的签名网址或签名请求 直接使用 RSA 密钥的密文 待签名字符串
带有 HMAC 密钥的签名网址或签名请求 从 HMAC 密钥的密文派生 待签名字符串

待签名字符串

待签名字符串包含有关请求的元信息以及您要签名的规范化请求的哈希值。

结构

待签名字符串必须采用 UTF-8 编码,并且具有以下结构,包括在各个元素之间使用换行符:

SIGNING_ALGORITHM
ACTIVE_DATETIME
CREDENTIAL_SCOPE
HASHED_CANONICAL_REQUEST

签名算法

用于 SIGNING_ALGORITHM 的值取决于您使用的密钥类型以及用于标头或查询参数的扩展程序:

用例 SIGNING_ALGORITHM”的值
x-goog-* 扩展程序和 RSA 密钥 GOOG4-RSA-SHA256
x-goog-* 扩展程序和 HMAC 密钥 GOOG4-HMAC-SHA256
x-amz-* 扩展程序和 HMAC 密钥 AWS4-HMAC-SHA256

有效日期时间

可以使用签名的日期和时间(采用 ISO 8601 基本格式 YYYYMMDD'T'HHMMSS'Z')。

  • 对于签名网址,签名从有效日期时间之前 15 分钟起可用,直到您指定的到期时间为止。有效日期时间必须与签名网址的 X-Goog-Date 查询字符串参数匹配,并且必须使用您在凭据范围中指定的相同日期。

  • 对于签名请求,签名从有效日期时间之前 15 分钟起可用,直到有效日期时间之后 15 分钟为止。有效日期时间必须与签名请求的 x-goog-date 请求标头匹配,并且必须使用您在凭据范围中指定的相同日期。

凭据范围

请求的凭据范围

规范化请求的哈希值

规范化请求的十六进制编码 SHA-256 哈希值。使用 SHA-256 哈希函数创建规范化请求的哈希值。您的编程语言应具有用于创建 SHA-256 哈希的库。示例哈希值如下所示:

436b7ce722d03b17d3f790255dd57904f7ed61c02ac5127a0ca8063877e4e42c

示例

以下是格式正确的待签名字符串示例,其换行符显示为实际的新行而非 \n

GOOG4-RSA-SHA256
20191201T190859Z
20191201/us-central1/storage/goog4_request
54f3076005db23fbecdb409d25c0ccb9fb8b5e24c59f12634654c0be13459af0

政策文档

政策文档定义有权访问相应 HTML 表单的用户可以上传到 Cloud Storage 的内容。政策文档可以提供授权以确保 HTML 表单能够将文件上传到目标存储分区。您可以使用政策文档来允许网站访问者将文件上传到 Cloud Storage。

政策文档是使用 JavaScript 对象表示法 (JSON) 构造的。政策文档必须采用 UTF-8 和 Base64 编码。政策文档包含以下部分:

条目 说明
expiration 政策文档的到期时间(采用 ISO 8601 基本格式 YYYYMMDD'T'HHMMSS'Z')。过期的政策文档会导致 HTML 表单无法使用。
conditions 每次上传都必须满足的一系列条件。

conditions 部分必须:

  • 对于您在 HTML 表单中使用的每个字段x-goog-signaturefilepolicy 字段除外),都必须包含一条条件语句。

  • 包含一条 "bucket" 条件语句,即使您未在 HTML 表单中使用存储分区字段也是如此。

如果您想要对同一字段使用多条条件语句,则应为每个字段创建单独的 HTML 表单。您可以在条件语句中使用三种类型的条件:

  • 完全匹配

    对字段执行完全匹配操作。在 HTML 表单的指定字段中使用的值必须与此条件中设置的值匹配。请使用以下任一语法样式设置此条件:

    {"field" : "value"}
    ["eq", "$field", "value"]

    Content-Length 之外的所有有效的 HTML 表单字段均可使用完全匹配。

  • 开头为

    如果某个字段的值必须以特定前缀开头,请使用 starts-with 条件,语法如下:

    ["starts-with", "$field", "value"]

    如果某个字段的值没有任何限制,请使用 starts-with 条件,语法如下:

    ["starts-with", "$field", ""]

    Content-Length 之外的所有有效的 HTML 表单字段均可使用 starts-with 条件。

  • 内容长度范围

    指定可在 Content-Length 字段中使用的可接受值范围。请使用以下语法指定此条件:

    ["content-length-range", min_range, max_range]

示例

以下是政策文档的示例:

{"expiration": "2020-06-16T11:11:11Z",
 "conditions": [
  ["starts-with", "$key", ""],
  {"bucket": "travel-maps"},
  {"success_action_redirect": "http://www.example.com/success_notification.html"},
  ["eq", "$Content-Type", "image/jpeg"],
  ["content-length-range", 0, 1000000],
  {"x-goog-algorithm": "GOOG4-RSA-SHA256"},
  {"x-goog-credential": "example_account@example_project.iam.gserviceaccount.com/20191102/auto/storage/goog4_request"},
  {"x-goog-date": "20191102T043530Z"}
  ]
}

此政策文档定义了以下条件:

  • 该表单的到期时间为世界协调时间 (UTC) 2020 年 6 月 16 日 11:11:11。
  • 文件名可以以任何有效的字符开头。
  • 该文件必须上传到存储分区 travel-maps
  • 如果上传成功,则用户会被重定向到 http://www.example.com/success_notification.html
  • 该表单仅允许上传图片。
  • 用户无法上传大于 1 MB 的文件。

凭据范围

凭据范围是一个同时出现在待签名字符串和政策文档中的字符串。凭据范围的结构如下:

DATE/LOCATION/SERVICE/REQUEST_TYPE

凭据范围包含以下组成部分:

  • DATE:可以使用签名的日期,格式为 YYYYMMDD。
  • LOCATION:对于 Cloud Storage 资源,您可以对 LOCATION 使用任何值:推荐使用的值为 auto。此参数存在的意义是保持与 Amazon S3 的兼容性。
  • SERVICE:服务名称。在大多数情况下,访问 Cloud Storage 资源时,此值为 storage。使用 Amazon S3 x-amz 扩展程序时,此值为 s3
  • REQUEST_TYPE:请求类型。在大多数情况下,访问 Cloud Storage 资源时,此值为 goog4_request。使用 Amazon S3 x-amz 扩展程序时,此值为 aws4_request

举例来说,典型的凭据范围如下所示:

20191102/auto/storage/goog4_request

将待签名字符串与 x-amz 扩展程序搭配使用时,凭据范围如下所示:

20150830/us-east-1/s3/aws4_request

签名

如需创建签名,您可以使用签名算法(也称为加密哈希函数)为待签名字符串或政策文档签名。您使用的签名算法取决于您拥有的身份验证密钥的类型:

身份验证密钥 签名算法 签名密钥
RSA 密钥 RSA-SHA256 直接使用 RSA 密钥的密文
HMAC 密钥 HMAC-SHA256 从 HMAC 密钥的密文派生

从 HMAC 密钥派生签名密钥

使用 HMAC 密钥进行签名时,您必须创建一个从 HMAC 密钥的密文派生的 UTF-8 编码签名密钥。该派生密钥特定于与您的请求相关联的日期、位置、服务和请求类型。以下伪代码展示了如何派生签名密钥:

key_date = HMAC-SHA256("PREFIX" + HMAC_KEY_SECRET, "DATE")
key_region = HMAC-SHA256(key_date, "LOCATION")
key_service = HMAC-SHA256(key_region, "SERVICE")
signing_key = HMAC-SHA256(key_service, "REQUEST_TYPE")

伪代码具有以下组件:

  • PREFIX:在大多数情况下,访问 Cloud Storage 资源时,此值为 GOOG4。使用 Amazon S3 x-amz 扩展程序时,此值为 AWS4
  • HMAC_KEY_SECRET:您用于发出请求以及为请求签名的 HMAC 密钥的密文。
  • DATELOCATIONSERVICEREQUEST_TYPE:这些值必须与凭据范围中指定的值匹配。

签名后

如需完成签名,您必须对签名的输出(称为“消息摘要”)进行十六进制编码。

示例

以下是用于为政策文档签名的伪代码:

EncodedPolicy = Base64Encode(PolicyDocument)
MessageDigest = SigningAlgorithm(SigningKey, EncodedPolicy)
Signature = HexEncode(MessageDigest)

以下是用于为待签名字符串签名的伪代码:

MessageDigest = SigningAlgorithm(SigningKey, StringToSign)
Signature = HexEncode(MessageDigest)

后续步骤