最近更新时间:2023-09-04 17:01:12
金山云OpenAPI支持一种签名算法:AWS签名算法版本4,您可以根据业务需要选择所使用的签名算法,请注意两种签名算法所使用的公共参数有所区别。
支持GET和POST两种HTTP方法,GET方法所有请求参数包括signature放置在url中,POST方法则将signature以名为Authorization header的形式放置在header中,其主要区别在于GET方式处理的请求url长度不能过长。
签名计算的主要流程如下:
在签名前,首先将请求进行正规化格式化,目的是让签名计算过程无二意,其主要过程伪代码如下:
CanonicalRequest = HTTPRequestMethod + '\n' + CanonicalURI + '\n' + CanonicalQueryString + '\n' + CanonicalHeaders + '\n' + SignedHeaders + '\n' + HexEncode(Hash(RequestPayload))
Hash指代计算哈希的算法,目前使用SHA-256,HexEncode是对哈希值进行用16进制编码(使用小写字母)。
具体步骤如下
=
连接,按照排序结果将“参数对”用&
连接CanonicalHeaders = CanonicalHeadersEntry0 + CanonicalHeadersEntry1 + ... + CanonicalHeadersEntryN
其中:
CanonicalHeadersEntry = Lowercase(HeaderName) + ':' + Trimall(HeaderValue) + '\n'
lowercase表示将header名字转为小写字母,trimall表示去掉header值前和值后的白空格,并将header值里面的连续白空格变成单空格,但是不去掉双引号中间的任何空格,且最后的正规化headers是按照header名称排序后的结果。
建议采用的CanonicalHeaders 如下:
CanonicalHeaders = 'host:' + host + '\n' + 'x-amz-date:' + RequestDate + '\n'
其中,
RequestDate是公共请求头X-Amz-Date的值,表示当前请求的时间和日期,格式YYYYMMDD’T’HHMMSS’Z’ ,例如:20210726T111901Z
SignedHeaders = Lowercase(HeaderName0) + ';' + Lowercase(HeaderName1) + ";" + ... + Lowercase(HeaderNameN)
对应上面建议的CanonicalHeaders,需采用如下的SignedHeaders :
SignedHeaders = 'host;x-amz-date'
然后处理请求body,如下
6. 对请求body使用哈希算法(SHA256)计算哈希值,并将二进制哈希值结果用16进制编码表示出来(且不使用大写字符),伪代码如下:
HashedPayload = Lowercase(HexEncode(Hash(requestPayload)))
HashedCanonicalRequest = Lowercase(HexEncode(Hash(CanonicalRequest)))
签名字符串主要包含请求以及正规化请求的元数据信息,由签名算法、请求日期、信任状和正规化请求哈希值连接组成,伪代码如下:
StringToSign = Algorithm + '\n' + RequestDate + '\n' + CredentialScope + '\n' + HashedCanonicalRequest
其中,
签名算法(Algorithm)为AWS4-HMAC-SHA256;
请求日期(RequestDate)是公共请求头X-Amz-Date的值,表示当前请求的日期和时间,格式YYYYMMDD’T’HHMMSS’Z’ ,例如:20210726T111901Z;
信任状(CredentialScope)格式为;YYYYMMDD/Region/Service/aws4_request;
正规化请求哈希值(HashedCanonicalRequest )为上述1中第8步的结果(注意结尾不附加“换行符”)。
注意:
YYYYMMDD取自RequestDate中的日期,对应上面的示例为20210726
Region为cn-beijing-6
Service为cdn
在计算签名前,首先从私有访问密钥(secret AccessKey)派生出签名密钥(signing key),而不是直接使用私有访问密钥;之后使用签名密钥和2中计算的签名字符串来计算签名值,具体计算过程如下
kSecret = *Your KSC Secret Access Key*
kDate = HMAC("AWS4" + kSecret, Date)
kRegion = HMAC(kDate, Region)
kService = HMAC(kRegion, Service)
kSigning = HMAC(kService, "aws4_request")
其方式是通过HMAC算法依次生成下一个HMAC的key值(第一个为私有访问密钥字符串),而message值则依次为信任状中的各项内容(Date、Region、Service、字符串"aws4_request");HMAC算法采用HMAC-SHA256,返回值为哈希值二进制形式(256bit,32字节),不需要做8/16进制编码显示。
注意:
Date为YYYYMMDD,取自RequestDate中的日期,对应上面的示例为20210726
Region为cn-beijing-6
Service为cdn
signature = HexEncode(HMAC(derived-signing-key, string-to-sign))
使用HMAC-SHA256算法,以签名密钥作为key,签名字符串作为data计算签名,签名后的二进制哈希值结果以16进制编码输出。
通过 RESTful API 对 CDN 发起的 HTTP 签名请求,可以通过以下方式传递签名:
签名头格式如下:
Authorization: Algorithm + ' ' + 'Credential=' + AccessKeyID + '/' + CredentialScope + ', ' + 'SignedHeaders=' + SignedHeaders + ', ' + 'Signature=' + signature
其中,
Algorithm为AWS4-HMAC-SHA256;
AccessKeyID为访问密钥ID;
CredentialScope格式为YYYYMMDD/Region/Service/aws4_request;
SignedHeaders为签名headers,取值如上所述
signature为签名值,取值如上所述
注意:
YYYYMMDD取自RequestDate中的日期,对应上面的示例为20210726
Region为cn-beijing-6
Service为cdn
GET /2016-09-01/domain/GetDomainConfigs?DomainId=2D08BTW HTTP/1.1
User-Agent: python-requests/2.23.0
accept-encoding: gzip
accept: */*
connection: keep-alive
host: cdn.api.ksyun.com
x-action: GetDomainConfigs
x-version: 2016-09-01
x-amz-date: 20210726T111902Z
Authorization: AWS4-HMAC-SHA256 Credential=LVLBPx7VDwlJRQGkpODXBCCruZ/20210726/cn-beijing-6/cdn/aws4_request, SignedHeaders=host;x-amz-date, Signature=cef04283a6cd6babf04x7f1ab132xq0ac7cd7q81537beqedbd4d9495f8a8axe3
POST /2016-09-01/domain/GetDomainConfigs HTTP/1.1
Host: cdn.api.ksyun.com
User-Agent: python-requests/2.23.0
Accept-Encoding: gzip, deflate
Accept: application/json
Connection: keep-alive
content-type: application/json
x-amz-date: 20210726T111901Z
authorization: AWS4-HMAC-SHA256 Credential=LVLBPx7VDwlJRQGkpODXBCCruZ/20210726/cn-shanghai-1/cdn/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature=cef04283a6cd6babf04x7f1ab132xq0ac7cd7q81537beqedbd4d9495f8a8axe3
X-version: 2016-09-01
X-action: GetDomainConfigs
Content-Length: 22
{“DomainId”:“2D08BTW”}
主要SDK:
其他语言签名算法参考:
纯净模式