You need to enable JavaScript to run this app.
导航

签名机制

最近更新时间2023.03.31 16:49:06

首次发布时间2021.11.10 18:21:34

对于每一次HTTP或者HTTPS协议请求,我们会根据访问中的签名信息验证访问请求者身份。具体由使用AccessKeyID和AccessKey Secret对称加密验证实现。

步骤一:获取AK/SK

主账户和有权限的子用户可以新建AK密钥,操作如下:

  1. 使用帐号/密码登录控制台。
  2. 选择一级菜单访问控制 > 密钥管理
  3. 页面展示主账号的访问密钥列表,每个IAM用户最多可同时拥有2个访问密钥,如果当前IAM用户的访问密钥数量未达到上限,则可以单击新建密钥
  4. 单击查看AccessKey详情,可直接查看访问密钥信息。

步骤二:创建一个正规化请求

CanonicalRequest = HTTPRequestMethod + '\n' + CanonicalURI + '\n' + CanonicalQueryString + '\n' + CanonicalHeaders + '\n' + SignedHeaders + '\n' + HexEncode(Hash(RequestPayload))

说明

  • Hash代指SHA256算法。
  • HexEncode代指转16进制编码。

在签名之前,首先要将请求正规化,目的是让签名计算过程无异议,其主要过程及伪代码如下:
HTTPRequestMethod
指代http请求的method,例如:GET等。
CanonicalURI
指代正规化后的URI。如果URI为空,那么使用"/"作为绝对路径。在火山引擎中绝大多数接口的URI都为"/"。
CanonicalQueryString
指代正规化后的Query String。对于Query String的正规化大致的过程如下:

  • URI编码每一个querystring参数名称和参数值。
  • 按照ASCII字节顺序对参数名称严格排序。
  • 将排序好的参数名称和参数值用=连接,按照排序结果将“参数对”用&连接。
    例如:
    CanonicalQueryString = "Action=ListUsers&Version=2020-04-01"
    

CanonicalHeaders
指代正规化后的Header。其中伪代码如下:

CanonicalHeaders = CanonicalHeadersEntry0 + CanonicalHeadersEntry1 + ... + CanonicalHeadersEntryN

其中

CanonicalHeadersEntry = Lowercase(HeaderName) + ':' + Trimall(HeaderValue) + '\n'

Lowcase代表将Header的名称全部转化成小写,Trimall表示去掉Header的值的前后多余的空格。
特别注意:最后需要添加"\n"的换行符。
SignedHeaders
代指参与签名的header名称。签名header是包含在正规化headers中名称列表,其目的是指明哪些header参与签名计算,从而忽略请求被proxy添加的额外header,其中host、x-date两个header如果存在则必须添加进来,伪代码如下:

SignedHeaders = Lowercase(HeaderName0) + ';' + Lowercase(HeaderName1) + ";" + ... + Lowercase(HeaderNameN)

RequestPayload
指代完整的请求的body。

  • URI编码(注:同RFC3986方法)每一个querystring参数名称和参数值(注:GET方式需要包含哈希算法、信任状、签名日期和签名header等全部参数)。
  • 按照ASCII字节顺序对参数名称严格排序。
  • 将排序好的参数名称和参数值用=连接,按照排序结果将“参数对”用&连接。

步骤三:创建签名字符串

签名字符串主要包含请求以及正规化请求的元数据信息,由签名算法、请求日期、信任状和正规化请求哈希值连接组成,伪代码如下:

StringToSign = Algorithm + '\n' + RequestDate + '\n' + CredentialScope + '\n' + HexEncode(Hash(CanonicalRequest))

Algorithm
指代签名的算法,目前火山引擎仅支持HMAC-SHA256的签名算法。
RequestDate
指代请求UTC时间,请使用如下格式:YYYYMMDD'T'HHMMSS'Z' 。
CredentialScope
指代信任状,格式为:YYYYMMDD/region/service/request。
CanonicalRequest
指代上一小节正规化请求的结果。

计算签名秘钥(signing-key)

在计算签名前,首先从私有访问密钥(AccessKey Secret)派生出签名密钥(signing key),而不是直接使用私有访问密钥。具体计算过程如下:

kSecret = *Your AccessKey Secret*
kDate = HMAC(kSecret, Date)
kRegion = HMAC(kDate, Region)
kService = HMAC(kRegion, Service)
kSigning = HMAC(kService, "request")

步骤四:计算签名

Signature = HexEncode(HMAC(kSigning, StringToSign))

步骤五:构建header

Authorization: HMAC-SHA256 Credential={CredentialScope}, SignedHeaders={SignedHeaders}, Signature={Signature}

说明

表达式中用{}括起来的代表上文计算出的中间过程。