在Header中包含V4签名(推荐)

更新时间:2025-04-11 06:56:35

向 OSS 发起请求时,添加包含 V4 签名的 Authorization 请求头(Header),以确保请求能够通过身份验证。优先使用 OSS 提供的 SDK 发起请求,因为 SDK 已集成复杂的 V4 签名算法。只有在无法使用 SDK 时,才需要参考本文自行实现 V4 签名算法。

SDK 签名实现

如果需要自行实现 V4 签名算法,优先参考 SDK 的 V4 签名实现。

Authorization 请求头

向 OSS 发起请求时,需在 Authorization 请求头中包含签名,用于验证请求。

Authorization 请求头格式如下:

Authorization: OSS4-HMAC-SHA256 Credential=<AccessKeyId>/<SignDate>/<SignRegion>/oss/aliyun_v4_request, AdditionalHeaders=<AdditionalHeadersVal>, Signature=<SignatureVal>

Authorization 请求头说明如下:

组成部分

说明

组成部分

说明

OSS4-HMAC-SHA256

用于指定计算签名的算法。该字符串指定了 OSS V4 签名版本(OSS4)和签名算法(HMAC-SHA256)。当您使用 V4 签名进行身份验证时,必须提供此值。

Credential

AccessKey ID和范围信息(包括用于计算签名的日期、地域和云产品)。当您使用 V4 签名进行身份验证时,必须提供该字段。

格式如下:

<AccessKeyId>/<SignDate>/<SignRegion>/oss/aliyun_v4_request

其中:

  • AccessKeyId:您的AccessKey ID。这是一个唯一的标识符,用于验证请求的发起者身份。

  • SignDate:签名日期,以 YYYYMMDD 格式表示。

  • SignRegion: 请求所使用的地域ID,例如 cn-hangzhou。

  • oss:固定字符串,标识请求所针对的服务是阿里云对象存储OSS。

  • aliyun_v4_request:固定字符串,指定请求的签名版本为V4。

AdditionalHeaders

指定参与计算签名的可选请求头(不需要指定必须参与签名的请求头),仅包含小写的头名称,并按字典序排序,以分号(;)分隔。

示例如下:

content-disposition;content-length

Signature

计算得到的签名。当您使用 V4 签名进行身份验证时,必须提供该字段。

用 64 个小写的十六进制数字表示的256 位的签名值示例如下:

3938**********************************dcdc

签名计算

OSS 收到请求后,会计算签名,并与 Authorization 请求头中的签名对比。如果一致,则请求成功;否则,请求失败。

签名计算过程

签名计算过程如下图所示:

image

签名计算过程分为以下三步:

  1. 构造规范化请求:按照 OSS 签名定义的规范,对请求进行格式化,得到规范化请求

  2. 构造待签名字符串:对规范化请求进行统一计算处理,得到待签名字符串

  3. 计算签名:对 AccessKey Secret 进行多步哈希运算生成派生密钥,然后使用派生密钥对待签名字符串进行计算,最终得到签名

1. 构造规范化请求

规范化请求格式如下:

HTTP Verb + "\n" +
Canonical URI + "\n" +
Canonical Query String + "\n" +
Canonical Headers + "\n" +
Additional Headers + "\n" +
Hashed PayLoad

规范化请求说明如下:

参数

说明

参数

说明

HTTP Verb

HTTP 请求方法,包含PUT、GET、POST、HEAD、DELETE、OPTIONS等。

Canonical URI

URI 编码的资源路径。资源路径不包含查询字符串,其中正斜线(/)不需要编码。

  • 如果请求目标为OSS服务,则资源路径为/,URI 编码的资源路径为UriEncode("/")

  • 如果请求目标为Bucket,则资源路径:/examplebucket/,URI 编码的资源路径为UriEncode("/examplebucket/")

  • 如果请求目标为Bucket中的Object,则资源路径:/examplebucket/exampleobject,URI 编码的资源路径:UriEncode("/examplebucket/exampleobject")

Canonical Query String

按字典排序的URI编码的查询参数。

  • 如果查询参数包含参数名称和值,先对每个参数的名称和值分别进行 URI 编码,然后按照参数名称的字典顺序对参数进行排序。注意,排序是在编码之后进行的。使用 = 连接编码后的名称和值,并使用 & 连接不同的参数。

    • 查询参数:prefix=somePrefix&marker=someMarker&max-keys=20

    • 规范化的查询参数:

      UriEncode("marker")+"="+UriEncode("someMarker")+"&"+UriEncode("max-keys")+"="+UriEncode("20")+"&"+UriEncode("prefix")+"="+UriEncode("somePrefix")
  • 如果查询参数只包含参数名称,只对参数名称进行 URI 编码,并按照 参数名称= 的格式构建格式化查询。

    • 查询参数:?acl

    • 规范化的查询参数:UriEncode("acl") + "=" + ""

  • 如果没有查询参数,即请求的 URI 中不包含 ?,则规范化的查询字符串设为空字符串("")。

Canonical Headers

请求头列表。

请求头包含以下三类:

  • 请求头中必须存在且参与签名的:

    • x-oss-content-sha256:目前只支持UNSIGNED-PAYLOAD。

  • 请求头中如果存在则参与签名的:

    • Content-Type

    • Content-MD5

    • x-oss-*:以x-oss-开头的其他请求头。例如,通过 STS AK 来访问的时候,SecurityToken 通过 x-oss-security-token:security-token 来描述。例如,请求时间通过x-oss-date来描述,格式必须为ISO8601标准时间格式,例如20231203T121212Z

  • AdditionalHeaders中指定的可选请求头。

格式如下:

Lowercase(<HeaderName1>) + ":" + Trim(<value>) + "\n"
Lowercase(<HeaderName2>) + ":" + Trim(<value>) + "\n"
...
Lowercase(<HeaderNameN>) + ":" + Trim(<value>) + "\n"

示例如下:

content-disposition:attachment
content-length:3
content-md5:ICy5YqxZB1uWSwcVLSNLcA==
content-type:text/plain
x-oss-content-sha256:UNSIGNED-PAYLOAD
x-oss-date:20250328T101048Z

Additional Headers

指定参与计算签名的可选请求头(不需要指定必须参与签名的请求头),仅包含小写的头名称,并按字典序排序,以分号(;)分隔,和AdditionalHeaders保持一致。

示例如下:

content-disposition;content-length

Hashed PayLoad

请求负载的 SHA256 哈希值的十六进制表现形式。目前只支持取值为UNSIGNED-PAYLOAD

2. 构造待签名字符串

待签名字符串格式如下:

"OSS4-HMAC-SHA256" + "\n" +
TimeStamp + "\n" +
Scope + "\n" +
Hex(SHA256Hash(<CanonicalRequest>))

待签名字符串说明如下:

参数

说明

参数

说明

OSS4-HMAC-SHA256

签名哈希算法,取值必须是OSS4-HMAC-SHA256

TimeStamp

当前UTC时间,格式必须是ISO8601,例如20250320T083322Z

Scope

获取派生密钥的参数集。该参数集指明了日期、地域和服务。因此,通过派生密钥计算的签名只能在指定的日期、地域和服务中有效。

格式如下:

<SignDate>/<SignRegion>/oss/aliyun_v4_request

说明如下:

  • SignDate:参与签名的日期,以 YYYYMMDD格式表示。

  • SignRegion:参与签名所使用的地域ID,例如 cn-hangzhou

  • oss:参与签名的服务名称,固定为oss

  • aliyun_v4_request:参与签名的版本,固定为aliyun_v4_request

CanonicalRequest

构造的规范化请求。

3. 计算签名

计算签名分为以下两步:

  1. 计算 SigningKey

    DateKey = HMAC-SHA256("aliyun_v4" + SK, Date);
    DateRegionKey = HMAC-SHA256(DateKey, Region);
    DateRegionServiceKey = HMAC-SHA256(DateRegionKey, "oss");
    SigningKey = HMAC-SHA256(DateRegionServiceKey, "aliyun_v4_request");
    • SK:参与签名的AccessKey Secret。

    • Date:参与签名的日期,以 YYYYMMDD 格式表示,必须和待签名字符串中的SignDate一致。

    • Region:参与签名所使用的地域ID,例如 cn-hangzhou,必须和待签名字符串中的SignRegion一致。

  2. 使用 SigningKey 与待签名字符串计算 Signature

    Signature = HEX(HMAC-SHA256(SigningKey, StringToSign))

签名计算示例

以 PutObject 为例,进行签名计算。

签名计算参数

参数

参数

AccessKeyId

LTAI****************

AccessKeySecret

yourAccessKeySecret

Timestamp

20250411T064124Z

Bucket

examplebucket

Object

exampleobject

Region

cn-hangzhou

签名计算过程示例

  1. 构造规范化请求。

    PUT
    /examplebucket/exampleobject
    
    content-disposition:attachment
    content-length:3
    content-md5:ICy5YqxZB1uWSwcVLSNLcA==
    content-type:text/plain
    x-oss-content-sha256:UNSIGNED-PAYLOAD
    x-oss-date:20250411T064124Z
    
    content-disposition;content-length
    UNSIGNED-PAYLOAD
  2. 构造待签名字符串。

    OSS4-HMAC-SHA256
    20250411T064124Z
    20250411/cn-hangzhou/oss/aliyun_v4_request
    c46d96390bdbc2d739ac9363293ae9d710b14e48081fcb22cd8ad54b63136eca
  3. 计算签名。

    1. 计算SigningKey。

      说明

      为便于阅读,以下SigningKey以十六进制格式展示。

      3543b7686e65eda71e5e5ca19d548d78423c37e8ddba4dc9d83f90228b457c76
    2. 计算Signature。

      053edbf550ebd239b32a9cdfd93b0b2b3f2d223083aa61f75e9ac16856d61f23
  • 本页导读 (1)
  • SDK 签名实现
  • Authorization 请求头
  • 签名计算
  • 签名计算过程
  • 1. 构造规范化请求
  • 2. 构造待签名字符串
  • 3. 计算签名
  • 签名计算示例
AI助理

点击开启售前

在线咨询服务

你好,我是AI助理

可以解答问题、推荐解决方案等