以下是基于HTTP头部签名方式的请求的Authorization标头值的示例。 为了便于阅读,在此示例中添加换行符:
Authorization: AWS4-HMAC-SHA256
Credential=AKIAIOSFODNN7EXAMPLE/20161208/US/s3/aws4_request,
SignedHeaders=host;range;x-amz-date,
Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024
注意:
AWS4-HMAC-SHA256和Credential之间存在一个空格
Credential,SignedHeaders和Signature由逗号分隔。
下表描述了上例中的各字段的说明:
名称 | 描述 |
---|---|
AWS4-HMAC-SHA256 | 用于计算签名的算法。 当您使用AWS签名版本4进行身份验证时,必须提供此值。该字符串指定AWS签名版本4(AWS4)和签名算法(HMAC-SHA256)。 |
Credential | 您的访问密钥和地域信息,包括用于计算签名的日期,区域等信息。此字符串具有以下形式: *<your-access-key>*/*<date>*/*<aws-region>*/***s3***/aws4_request Where: <date> value is specified using YYYYMMDD format.<aws-region> 主要用于后端记录用户的地域信息,目前未限定具体值 |
SignedHeaders | 以分号分隔的请求标头列表,用于计算Signature。 该列表仅包括头名称,并且头名称必须为小写。 例如:host;range;x-amz-date |
Signature | 它表示为64个小写十六进制字符的256位签名. 例如:fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024 |
签名计算因您选择传输请求有效内容的方法而异。
S3支持以下选项:
传输内容校验:您可以选择计算整个有效负载校验和,并将其包括在签名计算中。 这提供了增加的安全性,但你需要读取你的有效载荷两次或缓冲在内存中。例如,为了上传文件,您需要首先读取文件以计算用于签名计算的有效负载哈希,并在创建请求时再次传输。 对于较小的有效载荷。
如何计算签名
如图所示签名的过程包括如下几步:
1.规范化请求
2.生成待签名字符串
3.签名
下表描述了图中显示的功能。 您需要实现这些功能的代码。
函数 | 描述 |
---|---|
Lowercase() | 将字符转换为小写 |
Hex() | 十六进制编码 |
SHA256Hash() | 安全散列算法(SHA)加密散列函数。 |
HMAC-SHA256() | 通过使用提供了签名密钥的SHA256算法来计算HMAC。 这是最终的签名。 |
Trim() | 删除任何前导或尾随空格。 |
UriEncode() | 对每个字节进行URI编码。 UriEncode()必须强制执行以下规则:对非保留字符外的每个字符进行编码,非保留字符包括:‘A’ - ‘Z’,‘a’ - ‘z’,‘0’ - ‘9’,’ - ‘,’。‘,’_‘和’〜’。空格字符是保留字符,必须编码为“%20”(而不是“+”)。每个URI编码字节由“%”和字节的两位十六进制值组成。十六进制值中的字母必须为大写,例如“%1A”。在除了对象键名称以外的任何地方编码正斜杠字符’/'。 例如,如果对象键名称为photos/Jan/sample.jpg,则键名称中的正斜杠不会被编码。 注意由于RFC中的实现和相关歧义的差异,您的开发平台提供的标准UriEncode函数可能无法工作。 我们建议您编写自己的自定义UriEncode函数,以确保您的编码将工作。 |
规范化请求
本节提供了创建规范请求的概述。
以下是Amazon S3用于计算签名的规范请求格式。 要使签名匹配,您必须使用以下格式创建规范请求:
<HTTPMethod>
<CanonicalURI>
<CanonicalQueryString>
<CanonicalHeaders>
<SignedHeaders>
<HashedPayload>
HTTPMethod是其中一种HTTP方法,例如GET,PUT,HEAD和DELETE。
CanonicalURI是URI的绝对路径组件的URI编码版本 - 以域名后面的“/”开头,直到字符串的末尾或以问号字符(‘?’)开头的所有内容 查询字符串参数。 以下示例中的URI /examplebucket/myphoto.jpg是绝对路径,并且不在绝对路径中对“/”进行编码:
http://s3-us-east-1.ossfiles.com/examplebucket/myphoto.jpg
CanonicalQueryString指定URI编码的查询字符串参数。 您分别对URI和URI进行编码。 您还必须按键名称按字母顺序对规范查询字符串中的参数进行排序。 编码后进行排序。 以下URI示例中的查询字符串为:
prefix=somePrefix&marker=someMarker:
http://s3-us-east-1.ossfiles.com/examplebucket?prefix=somePrefix&marker=someMarker
规范查询字符串如下(为了便于阅读,在此示例中添加换行符):
URI-encode("marker")+"="+URI-encode("someMarker")+"&"+
URI-encode("prefix")+"="+URI-encode(“somePrefix")
当请求针对子资源时,相应的查询参数值将为空字符串(“”)。 例如,以下URI标识examplebucket存储桶上的ACL子资源:
http://s3-us-east-1.ossfiles.com/examplebucket?acl
在这种情况下,CanonicalQueryString如下:
URI-encode("acl") + "=" + ""
如果URI不包含’?',则请求中没有查询字符串,并且将规范查询字符串设置为空字符串(“”)。 您仍然需要添加“\ n”。
CanonicalHeaders是请求头及其值的列表。 单个标题名称和值对由换行符(“\ n”)分隔。 标题名称必须为小写。 您必须按字母顺序对标题名称进行排序以构造字符串,如以下示例所示:
Lowercase(<HeaderName1>)+":"+Trim(<value>)+"\n"
Lowercase(<HeaderName2>)+":"+Trim(<value>)+"\n"
...
Lowercase(<HeaderNameN>)+":"+Trim(<value>)+”\n"
在此示例中使用的Lowercase()和Trim()函数在前面的部分中描述。``
CanonicalHeaders列表必须包含以下内容:
HTTP host header。
您计划要包含在请求中的任何x-amz- *标头也必须添加。
下面是一个CanonicalHeaders字符串示例。 标题名称以小写字母排序。
host:s3-us-east-1.ossfiles.com
x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
x-amz-date:20130708T220855Z
SignedHeaders是按字母顺序排序的,以分号分隔的小写请求标题名称列表。 列表中的请求标头与您在CanonicalHeaders字符串中包含的标头相同。 例如,对于前面的示例,SignedHeaders的值如下:
host;x-amz-content-sha256;x-amz-date
HashedPayload是请求有效内容的SHA256散列的十六进制值。
Hex(SHA256Hash(<payload>)
如果请求中没有有效内容,则计算空字符串的哈希值,如下所示:
Hex(SHA256Hash(“”))
该哈希值返回以下值:
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
例如,当您通过使用PUT请求上传对象时,您在主体中提供对象数据。 当您通过使用GET请求检索对象时,将计算空字符串散列。
生成待签名字符串
本节提供了创建要签名的字符串的概述。
要签名的字符串是以下字符串的合并:
"AWS4-HMAC-SHA256" + "\n" +
timeStampISO8601Format + "\n" +
<Scope> + "\n" +
Hex(SHA256Hash(<CanonicalRequest>))
常量字符串AWS4-HMAC-SHA256指定您正在使用的哈希算法HMAC-SHA256。 timeStamp是ISO 8601格式的当前UTC时间(例如,20130524T000000Z)。
Scope 包含特定日期,A区域和服务。 因此,您的结果签名将仅在特定区域和特定服务中工作。 签名在指定日期后的七天内有效。
date.Format(<YYYYMMDD>) + "/" + <region> + "/" + <service> + “/aws4_request"
region用于指定存储的机房区域,目前该指定没有特殊要求
serverice 字段值为s3
如下实例:
20130606/northchina-1/s3/aws4_request
计算签名
在AWS签名版本4中,您不是直接使用ACCESS KEY来签署请求,而是首先基于ACCESS KEY创建一个范围限于特定区域和服务的签名密钥。
DateKey = HMAC-SHA256("AWS4"+"<SecretAccessKey>", "<YYYYMMDD>")
DateRegionKey = HMAC-SHA256(<DateKey>, "<aws-region>")
DateRegionServiceKey = HMAC-SHA256(<DateRegionKey>, "<aws-service>")
SigningKey = HMAC-SHA256(<DateRegionServiceKey>, "aws4_request")
通过使用签名密钥,您可以将棱束链对象存储凭据保存在一个安全的位置。 例如,如果您有多个与棱束链对象存储通信的服务器,则会与这些服务器共享签名密钥; 您不必在每个服务器上保留您的秘密访问密钥的副本。 签名密钥最多有效期为7天。 因此,每次计算签名密钥时,您都需要与服务器共享签名密钥。
最终签名是要签名的字符串的HMAC-SHA256散列,使用签名密钥作为密钥。
HMAC-SHA256(SigningKey, StringToSign)
示例:签名计算
您可以使用本节中的示例作为检查代码中签名计算的参考。 示例中所示的计算使用以下数据:
示例账号信息
Parameter | Value |
---|---|
AWSAccessKeyId |
AKIAIOSFODNN7EXAMPLE |
AWSSecretAccessKey |
wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY |
请求的 timestamp of 20130524T000000Z (Fri, 24 May 2013 00:00:00 GMT
).
桶名examplebucket
.
假设bucket所在的region是美国东部
您可以使用路径样式或桶的子域名样式。 以下示例显示如何签名路径样式请求,例如:
https://examplebucket.s3.amazonaws.com/photos/photo1.jpg
示例:获取对象
以下示例从examplebucket获取对象(test.txt)的前10个字节。 有关API操作的更多信息,请参阅GET对象。
GET /test.txt HTTP/1.1
Host: examplebucket.s3.amazonaws.com
Authorization: SignatureToBeCalculated
Range: bytes=0-9
x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
x-amz-date: 20130524T000000Z
因为此GET请求不提供任何正文内容,所以x-amz-content-sha256值是空请求正文的哈希值。 以下步骤显示了签名计算和授权头的构造。
生成待签名字符串
规范化请求
GET
/test.txt
host:examplebucket.s3.amazonaws.com
range:bytes=0-9
x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
x-amz-date:20130524T000000Z
host;range;x-amz-content-sha256;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
在规范请求字符串中,最后一行是空请求主体的哈希。 第三行为空,因为请求中没有查询参数。
生成待签名字符串
AWS4-HMAC-SHA256
20130524T000000Z
20130524/us-east-1/s3/aws4_request
7344ae5b7ee6c3e7e6b0fe0640412a37625d1fbfff95c48bbb2dc43964946972
生成签名秘钥
signing key = HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("AWS4" + "<YourSecretAccessKey>","20130524"),"us-east-1"),"s3"),"aws4_request")
签名
f0e8bdb87c964420e857bd35b5d6ed310bd44f0170aba48dd91039c6036bdb41
生成认证头部
AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;range;x-amz-content-sha256;x-amz-date,Signature=f0e8bdb87c964420e857bd35b5d6ed310bd44f0170aba48dd91039c6036bdb41