分块传输认证 (HTTP Chunked Transfer)
分块传输认证仅针对 新建对象 过程中的 分块传输模式 有效,且只支持 AWS V4 认证方式。
传输步骤定义
1, 客户端按照以下 认证签名 的定义生成认证签名,并将其作为 ChunkHashSeed 初始化值
2, 客户端生成当前上传块并按照以下 分块签名 的定义计算当前上传块的 HASH 值
3, 客户端用当前上传块的 HASH 值更新 ChunkHashSeed 值作为后续块 HASH 计算的 Seed,并重复步骤 2 和 3
4, 客户端发送最后一个大小为 0 的块和对应的 HASH 值完成上传
分块格式定义
string(Hexadecimal(<Chunk-Size)) + ";chunk-signature=" + <Chunk-Signature> + "\r\n" + <Chunk-Bytes> + "\r\n"
string(Hexadecimal(<Chunk-Size))
,指定当前上传块的大小,以十六进制表示;如当前上传块为 65536 (bytes),则十六进制字串为 "10000"。<Chunk-Signature>
,按照 分块签名 的定义计算当前上传块的签名字串
认证签名
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 = "STREAMING-AWS4-HMAC-SHA256-PAYLOAD"
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 = Hex(HMAC-SHA256(SigningKey, UTF-8-Encoding-Of(StringToSign)))
Authorization = "AWS4-HMAC-SHA256" + " " +
"Credential=<YourAccessKeySecret>/<CanonicalizedScope>" + "," +
"SignedHeaders=<SignedHeaders>" + "," +
"Signature=<Signature>"
分块签名
注意: CanonicalizedTimestamp 和 CanonicalizedScope 的值与 认证签名 中对应的值相同,ChunkHashSeed 的初始值为 认证签名 中 Signature 值。
CanonicalizedTimestamp = ISO8601(...)
CanonicalizedScope = <yyyymmdd>/<region>/<service>/aws4_request
ChunkHashSeed = <Signature>
StringToSign = AWS4-HMAC-SHA256-PAYLOAD + "\n" +
CanonicalizedTimestamp + "\n" +
CanonicalizedScope + "\n" +
ChunkHashSeed + "\n" +
Hex(HMAC-SHA256("")) + "\n" +
Hex(HMAC-SHA256(CurrentChunkBytes))
SigningKey = HMAC-SHA256("AWS4" + "<YourAccessKeySecret>", "<yyyymmdd>")
SigningKey = HMAC-SHA256(SigningKey, "<region>")
SigningKey = HMAC-SHA256(SigningKey, "<service>")
SigningKey = HMAC-SHA256(SigningKey, "aws4_request")
chunk-signature = Hex(HMAC-SHA256(SigningKey, UTF-8-Encoding-Of(StringToSign)))
分块传输示例
假设上传的对象内容为 65KB 文本文件,内容全部为字母 "a", 并且 Access Key Id 和 Access Key Secret 定义如下:
名称 | 值 |
---|---|
Id | WeyUtAXps-_5dIDvFWF-rKZ5XyzWf-BmOEI_vNtk |
Secret | wHKb0KxX0iddrKM35WRbEzCRxOPDq6vqewgla87L |
- 请求
注意: 为方便阅读 Authorization 字段添加了换行符和缩进格式,实际请求中不能包含换行符
PUT /mybucket/mydocs/chunked.txt HTTP/1.1
Host: api-s3.qiniu.com
Date: Mon, 02 Jan 2006 15:04:05 GMT
Content-Encoding: aws-chunked
Authorization: AWS4-HMAC-SHA256 Credential=WeyUtAXps-_5dIDvFWF-rKZ5XyzWf-BmOEI_vNtk/20060102/cn-east-1/s3/aws4_request,
SignedHeaders=content-encoding;content-length;host;x-amz-content-sha256;x-amz-date;x-amz-decoded-content-length;x-amz-storage-class,
Signature=50a559a3588b3e17c3da9dd3709a78ee9f1eda5506dd35c250f732b993082e63
X-Amz-Content-Sha256: STREAMING-AWS4-HMAC-SHA256-PAYLOAD
X-Amz-Decoded-Content-Length: 66560
X-Amz-Storage-Class: STANDARD
- SigningKey
[]byte{0x95, 0x77, 0xd, 0x68, 0x6a, 0x13, 0x26, 0x45, 0xbd, 0x7d, 0x83, 0x37, 0x94, 0x5e, 0x75, 0xa9, 0xa8, 0xb4, 0xac, 0xae, 0x8d, 0x21, 0x3c, 0x67, 0x66, 0xcd, 0x39, 0x6f, 0xf7, 0xc, 0x54, 0x5f}
- ChunkHashSeed 初始值
50a559a3588b3e17c3da9dd3709a78ee9f1eda5506dd35c250f732b993082e63
- 分块签名
本示例将 65KB 的文件分为 64KB 和 1KB 两个块,具体每个块的签名过程如下:
第 1 块 (Chunk 1)
第 1 块大小为 64KB,即 65536 个字母 "a"。
- 规则化签名字串
AWS4-HMAC-SHA256-PAYLOAD
Mon, 02 Jan 2006 15:04:05 GMT
20060102/cn-east-1/s3/aws4_request
50a559a3588b3e17c3da9dd3709a78ee9f1eda5506dd35c250f732b993082e63
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
bf718b6f653bebc184e1479f1935b8da974d701b893afcf49e701f3e2f9f9c5a
- 第 1 块签名
b51dc0b604326ed0bf66c04eb1a3db1a77a7993b10f6d64d010141c30b55ced1
- 第 1 块请求数据
10000;chunk-signature=b51dc0b604326ed0bf66c04eb1a3db1a77a7993b10f6d64d010141c30b55ced1\r\n<65536-bytes>\r\n
第 2 块 (Chunk 2)
第 2 块大小为 1KB,即 1024 个字母 "a"。
- 规则化签名字串
AWS4-HMAC-SHA256-PAYLOAD
Mon, 02 Jan 2006 15:04:05 GMT
20060102/cn-east-1/s3/aws4_request
b51dc0b604326ed0bf66c04eb1a3db1a77a7993b10f6d64d010141c30b55ced1
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
2edc986847e209b4016e141a6dc8716d3207350f416969382d431539bf292e4a
- 第 2 块签名
e797173de26f45957dd4975da4d64e2db774499121c64f4c0e8dd06282745a10
- 第 2 块请求数据
400;chunk-signature=e797173de26f45957dd4975da4d64e2db774499121c64f4c0e8dd06282745a10\r\n<1024-bytes>\r\n
第 3 块 (Chunk 3)
第 3 块大小为 0,即最后一块。
- 规则化签名字串
AWS4-HMAC-SHA256-PAYLOAD
Mon, 02 Jan 2006 15:04:05 GMT
20060102/cn-east-1/s3/aws4_request
e797173de26f45957dd4975da4d64e2db774499121c64f4c0e8dd06282745a10
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
- 第 3 块签名
8cfaf9e48b74b7188b2f042d4ef63231774de572d4f88690f5fc61491eb46293
- 第 3 块请求数据
0;chunk-signature=8cfaf9e48b74b7188b2f042d4ef63231774de572d4f88690f5fc61491eb46293\r\n\r\n