请求认证 (Authentication)
Qiniu S3 API 服务同时支持 AWS V4 和 AWS V2 请求签名认证,推荐优先选择 AWS V4 签名认证!
认证方式
HTTP 认证头 (HTTP Authorization Header)
Qiniu S3 API 服务支持基于 HTTP Authorization Header 认证方式。
HTTP 请求参数 (HTTP Query String)
Qiniu S3 API 服务支持基于 HTTP Query String 认证方式。
认证签名 V4
CanonicalizedURI = [ "/" + Bucket ] +
<HTTP-Request-URI, from the protocol name up to the query string>
CanonicalizedQueryString = URI-Encoding(<QueryParameter1>) + "=" + URI-Encoding(<Value1>) +
"&" + URI-Encoding(<QueryParameter2>) + "=" + URI-Encoding(<Value2>) +
...
"&" + URI-Encoding(<QueryParameterN>) + "=" + URI-Encoding(<ValueN>)
CanonicalizedHeaders = Lowercase(<HeaderName1>) + ":" + TrimSpace(<Value1>) + "\n"
Lowercase(<HeaderName2>) + ":" + TrimSpace(<Value2>) + "\n"
...
Lowercase(<HeaderNameN>) + ":" + TrimSpace(<ValueN>) + "\n"
SignedHeaders = Lowercase(<HeaderName1>) + ";" + Lowercase(<HeaderName2>) + ";" + ... + ";" + Lowercase(<HeaderNameN>)
HashedPayload = Hex(HMAC-SHA256(<Playload>))
CanonicalizedRequest = HTTP-Verb + "\n" +
CanonicalizedURI + "\n" +
CanonicalizedQueryString + "\n" +
CanonicalizedHeaders + "\n" +
SignedHeaders + "\n" +
HashedPayload
CanonicalizedTimestamp = ISO8601(...)
CanonicalizedScope = <yyyymmdd>/<region>/<service>/aws4_request
StringToSign = AWS4-HMAC-SHA256 + "\n" +
CanonicalizedTimestamp + "\n" +
CanonicalizedScope + "\n" +
Hex(HMAC-SHA256(CanonicalizedRequest))
SigningKey = HMAC-SHA256("AWS4" + "<YourAccessKeySecret>", "<yyyymmdd>")
SigningKey = HMAC-SHA256(SigningKey, "<region>")
SigningKey = HMAC-SHA256(SigningKey, "<service>")
SigningKey = HMAC-SHA256(SigningKey, "aws4_request")
Signature = HMAC-SHA256(SigningKey, UTF8-Encoding-Of(StringToSign))
Authorization = "AWS4-HMAC-SHA256" + " " +
"Credential=<YourAccessKeyId>/<CanonicalizedScope>" + "," +
"SignedHeaders=<SignedHeaders>" + "," +
"Signature=<Signature>"
AWS V4 认证签名的规则化流程
规则化请求 URI (CanonicalizedURI)
以空字符开始
CanonicalizedURI = ""
如果请求中包含 Bucket 名称,则将其添加到规则化请求 URI 中
CanonicalizedURI += "/<BuckentName>"
将请求中的 HTTP Request-URI 添加到规则化请求 URI 中
CanonicalizedURI += "/myphotos/gopher.png"
注意: 对于 List Buckets 请求,需要添加 "/" 到规则化请求 URI 中
CanonicalizedURI += "/"
规则化请求查询字串 (CanonicalizedQueryString)
将请求参数的 Keys 和 Values 使用 URI-Encoding 编码
将 URI-Encoding 编码后请求参数的 Keys 按字母序排序
用英文等号
=
将请求参数对连接成一个字串,如URI-Encoding(Key) + "=" + URI-Encoding(Value)
注意: 如果请求参数 Key 对应的值不存在,则用空字串代替,如
GET /?key
应转换为URI-Encoding("key") + "=" + ""
用英文
&
将多个请求参数对连接成一个字串,如URI-Encoding(Key1) + "=" + URI-Encoding(Value1) + "&" + URI-Encoding(Key2) + "=" + URI-Encoding(Value2)
规则化请求头 (CanonicalizedHeaders)
将请求头名称 (Header Name) 转换为小写 (lowercase) 格式,如
X-Amz-Date
应转换为x-amz-date
按字母序对请求头名称 (Header Name) 排序
如果同一请求头名称 (Header Name) 包含多个值,则使用英文逗号
,
将多个值合并成一个字串,并且移除值的前后空格,如x-amz-meta-username: Qiniu
和x-amz-meta-username: Amazon
应转换为x-amz-meta-username:Qiniu,Amazon
在每个规则化的请求头字串后面添加一个换行符
\n
字符 (U+000A)将所有规则化的请求头连接成一个字串
注意: 以下请求头必须包含在规则化请求头字串中!
Host
,请求域名Content-Type
,如果请求头包含该值X-Amz-*
,所有以 X-Amz- 开头的自定义请求头
认证签名请求头列表 (SignedHeaders)
用英文分号
;
连接的所有规则化请求头 CanonicalizedHeaders 的名字 (Header Name) 列表,如content-type;host;x-amz-content-sha256;x-amz-date
请求头名字必须以字母序排序
认证签名的请求体 HASH 值 (HashedPayload)
如果客户端需要对请求体做签名认证,该值的计算过程为
Hex(HMAC-SHA256(<Payload Bytes>))
如果客户端不需要对请求体做签名认证,该值应为
UNSIGNED-PAYLOAD
如果客户端通过 分块传输 模式上传对象,该值应为
STREAMING-AWS4-HMAC-SHA256-PAYLOAD
规则化请求字串 (CanonicalizedRequest)
请按照以下格式拼接规则化签名字串,如果请求中不包含对应的值则用空字串 ("") 代替,但行末的换行符 (\n) 不能省略!
HTTP-Verb + "\n" + CanonicalizedURI + "\n" + CanonicalizedQueryString + "\n" + CanonicalizedHeaders + "\n" + SignedHeaders + "\n" + HashedPayload
规则化请求时间 (CanonicalizedTimestamp)
- 按照 ISO 8601 格式化的时间,如 20060102T150304Z
规则化请求作用域 (CanonicalizedScope)
按照
<yyyymmdd> + "/" + <region> + "/" + <service> + "/aws4_request"
格式化的字串<yyyymmdd>
,必须与 CanonicalizedTimestamp 日期一致<region>
,请求对应的数据中心,如 cn-east-1, cn-north-1<service>
,目前仅支持 s3
规则化签名字串 (StringToSign)
请按照以下格式拼接规则化签名字串,如果请求中不包含对应的值则用空字串 ("") 代替,但行末的换行符 (\n) 不能省略!
AWS4-HMAC-SHA256 + "\n" + CanonicalizedTimestamp + "\n" + CanonicalizedScope + "\n" + Hex(HMAC-SHA256(CanonicalizedRequest))
生成签名私串 (SigningKey)
注意: 你必须按照以下顺序生成签名私串,即后面的签名必须使用上一步签名值!
对
CanonicalizedScope
的日期签名:DateSigningKey = HMAC-SHA256("AWS4" + "<YourAccessKeySecret>", "<yyyymmdd>")
对
CanonicalizedScope
的 < region > 签名:RegionSigningKey = HMAC-SHA256(DateSigningKey, "<region>")
对
CanonicalizedScope
的 < service > 签名:ServiceSigningKey = HMAC-SHA256(RegionSigningKey, "<service>")
对
CanonicalizedScope
的 "aws4_request" 签名:SigningKey = HMAC-SHA256(ServiceSigningKey, "aws4_request")
生成签名
- Signature = Hex(HMAC-SHA256(SigningKey, StringToSign))
AWS V4 认证签名示例
假设请求体为空,并且 Access Key Id 和 Access Key Secret 定义如下:
名称 | 值 |
---|---|
Id | WeyUtAXps-_5dIDvFWF-rKZ5XyzWf-BmOEI_vNtk |
Secret | wHKb0KxX0iddrKM35WRbEzCRxOPDq6vqewgla87L |
- 请求
注意: 为方便阅读 Authorization 字段添加了换行符和缩进格式,实际请求中不能包含换行符。
GET /mybucket/myphotos/gopher.png HTTP/1.1
Host: api-s3.qiniu.com
Date: Mon, 02 Jan 2006 15:04:05 GMT
Authorization: AWS4-HMAC-SHA256 Credential=WeyUtAXps-_5dIDvFWF-rKZ5XyzWf-BmOEI_vNtk/20060102/cn-east-1/s3/aws4_request,
SignedHeaders=date;host;x-amz-content-sha256,
Signature=80552f6b3632423fad2db5176badcd627eed2087cbd801cf06d4a9983bd4688d
X-Amz-Content-Sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
- 规则化请求字串
注意: 为方便阅读换行处添加了换行符
GET\n
/mybucket/myphotos/gopher.png\n
\n
date:Mon, 02 Jan 2006 15:04:05 GMT\n
host:api-s3.qiniu.com\n
x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\n
\n
date;host;x-amz-content-sha256\n
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
- 规则化签名字串
注意: 为方便阅读换行处添加了换行符
WS4-HMAC-SHA256\n
Mon, 02 Jan 2006 15:04:05 GMT\n
20130524/us-east-1/s3/aws4_request\n
3a5aae01842069b322e956a8c016e723beb9728fbcc3f8ad298cef1686d9876a
- 签名私串
[]byte{0x60, 0xe5, 0x48, 0xfd, 0xe8, 0xbb, 0x7b, 0x4d, 0x4d, 0x36, 0x17, 0xd7, 0xa4, 0xbf, 0xb8, 0xcd, 0xa5, 0xa, 0xf4, 0xca, 0x7e, 0xb1, 0xd8, 0xd5, 0x77, 0xf4, 0x52, 0xd4, 0xa4, 0x4e, 0xc3, 0x34}
- 签名字串
80552f6b3632423fad2db5176badcd627eed2087cbd801cf06d4a9983bd4688d
认证签名 V2
CanonicalizedResource = [ "/" + Bucket ] +
<HTTP-Request-URI, from the protocol name up to the query string> +
[ subresource, if present. For example "?uploads" and "?location"]
CanonicalizedAmzHeaders = Lowercase(<AmzHeaderName1>) + ":" + TrimSpace(<Value1>) + "\n"
Lowercase(<AmzHeaderName2>) + ":" + TrimSpace(<Value2>) + "\n"
...
Lowercase(<AmzHeaderNameN>) + ":" + TrimSpace(<ValueN>) + "\n"
StringToSign = HTTP-Verb + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedAmzHeaders +
CanonicalizedResource
Signature = Base64(HMAC-SHA1(AWSAccessKeySecret, UTF8-Encoding-Of(StringToSign)))
Authorization = "AWS" + " " + AWSAccessKeyId + ":" + Signature
AWS V2 认证签名的规则化流程
规则化请求资源 (CanonicalizedResource)
以空字符开始
CanonicalizedResource = ""
如果请求中包含 Bucket 名称,则将其添加到规则化请求资源中
CanonicalizedResource += "/<BuckentName>"
将请求中的 HTTP Request-URI 添加到规则化请求资源中
CanonicalizedResource += "/myphotos/gopher.png"
注意: 对于 List Buckets 请求,需要添加 "/" 到规则化请求资源中
CanonicalizedResource += "/"
如果请求中包含子资源 (sub resource),则将其添加到规则化请求资源中
CanonicalizedResource += "?delete"
注意: 多个子资源必须按照请求 Key 字母排序后再连接,如
CanonicalizedResource += "?uploads&location"
规则化 X-Amz-* 请求头 (CanonicalizedAmzHeaders)
将请求头名字 (Header Name) 转换为小写 (lowercase) 格式,如
X-Amz-Date
应转换为x-amz-date
将请求头 (Header Name) 名字按字母序排序
如果同一请求头名字 (Header Name) 包含多个值,则使用英文逗号 , 将多个值合并成一个字串,并且移除值的前后空格,如 x-amz-meta-username: Qiniu 和 x-amz-meta-username: Amazon 应转换为 x-amz-meta-username:Qiniu,Amazon
在每个规则化的请求头字串后面添加一个换行符
\n
字符 (U+000A)将所有规则化的请求头连接成一个字串
规则化签名字串 (StringToSign)
请按照以下格式拼接规则化签名字串,如果请求中不包含对应的值则用空字串 ("") 代替,但行末的换行符 (\n) 不能省略!
HTTP-Verb + "\n" + Content-MD5 + "\n" + Content-Type + "\n" + Date + "\n" + CanonicalizedAmzHeaders + CanonicalizedResource
Content-MD5
值仅计算请求体
生成签名
- Signature = Base64(HMAC-SHA1(AWSAccessKeySecret, StringToSign))
AWS V2 认证签名示例
假设请求体为空,并且 Access Key Id 和 Access Key Secret 定义如下:
名称 | 值 |
---|---|
Id | WeyUtAXps-_5dIDvFWF-rKZ5XyzWf-BmOEI_vNtk |
Secret | wHKb0KxX0iddrKM35WRbEzCRxOPDq6vqewgla87L |
- 请求
GET /mybucket/myphotos/gopher.png HTTP/1.1
Host: api-s3.qiniu.com
Date: Mon, 02 Jan 2006 15:04:05 GMT
Authorization: AWS WeyUtAXps-_5dIDvFWF-rKZ5XyzWf-BmOEI_vNtk:4+SXv0N2piq2S5vjEifeq7125L8=
- 规则化签名字串
GET\n
\n
\n
Mon, 02 Jan 2006 15:04:05 GMT\n
/mybucket/myphotos/gopher.png
- 签名字串
4+SXv0N2piq2S5vjEifeq7125L8=