HTTP头部签名

2022-09-24 20:26:17

HTTP头部签名

以下是基于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.签名

img

下表描述了图中显示的功能。 您需要实现这些功能的代码。

函数 描述
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