OBS API 鉴权实现宝典(中)—POST签名计算

举报
云技术搬运工 发表于 2020/09/15 14:30:51 2020/09/15
【摘要】 OBS服务支持基于浏览器的POST上传对象请求,此类请求的签名信息通过表单的方式上传。

OBS服务支持基于浏览器的POST上传对象请求,此类请求的签名信息通过表单的方式上传。POST上传对象的流程主要如下:

首先,创建一个安全策略,指定请求中需要满足的条件,比如:桶名、对象名前缀;

然后,创建一个基于此策略的签名,需要签名的请求表单中必须包含有效的signaturepolicy

最后,创建一个表单将对象上传到桶中。

1、基于浏览器上传的表单中携带签名

官网链接:https://support.huaweicloud.com/api-obs/obs_04_0012.html

1.1、签名的计算原理和计算方法

原理图示

1.png


计算方法

1.构造请求Policy:

例如一个最简单的请求Policy如下:

Policy = {

  "expiration": "2020-12-21T12:00:00.000Z",

  "conditions": [

    {

      "bucket": "obs-test"

    },

    [

      "eq",

      "$key",

      "post.txt"

    ],

 

  ]

}


2.对请求Policy进行UTF-8编码。

3.对第二步的结果进行Base64编码。

4.使用SK对第三步的结果进行HMAC-SHA1签名计算。

5.对第四步的结果进行Base64编码,得到签名。

签名如以下形式(28位长度的BASE64编码的字符串):

CVs7GTY6n8Gdhc74Gj+QhpbxtT4=

即:StringToSign = Base64( UTF-8-Encoding-Of( policy ) )

Signature = Base64( HMAC-SHA1( YourSecretAccessKeyID, StringToSign ) )

计算示例

例:需要通过浏览器表单上传对象”post.txt”到桶”obs-test”下,同时设置对象ACL为公共读,如何构造请求并计算签名?

1、首先构造请求Policy

设置请求过期时间:2020-12-21T12:00:00.000Z

桶名:obs-test

对象ACLpublic-read

匹配条件:对象名=post.txt

2、构造Policy如下:

{

  "expiration": "2020-12-21T12:00:00.000Z",

  "conditions": [

    {

      "bucket": "obs-test"

    },

    {

    "x-obs-acl": "public-read"

    },

    [

      "eq",

      "$key",

      "post.txt"

    ],

  ]

}

3、根据签名算法,将Policy进行UTF-8编码后再进行BASE64编码,再进行HMAC-SHA1计算后获得签名结果:odouyqpyXcYlKQz7G1/EaUNfJUE=


1.2、签名计算的实现方式

以Python计算签名代码为例,供参考:

1.  import hashlib  

2.  import hmac  

3.  import binascii  

4.    

5.  验证信息  

6.  SK = '您的secret_access_key_id'  

7.    

8.  # Policy  

9.  canonical_string = '''''{ 

10.   "expiration": "2020-12-21T12:00:00.000Z", 

11.   "conditions": [ 

12.     { 

13.       "bucket": "obs-test" 

14.     }, 

15.     { 

16.     "x-obs-acl": "public-read"  

17.     }, 

18.     [ 

19.       "eq", 

20.       "$key", 

21.       "post.txt" 

22.     ], 

23.   ] 

24. }'''  

25.   

26. policybase64 = binascii.b2a_base64(canonical_string.encode('utf-8'))  

27. policybase64 = policybase64[:-1].decode('UTF-8')  

28. # PolicyBase64编码  

29. print(policybase64)  

30. hashed = hmac.new(SK.encode('UTF-8'), policybase64.encode('UTF-8'), hashlib.sha1)  

31. encode_canonical = binascii.b2a_base64(hashed.digest())[:-1].decode('UTF-8')  

32. 签名  

33. print(encode_canonical)  


说明:

1. policy使用json格式,conditions可以支持 { }  [ ] 两种方式,{ }中包含表单元素的keyvalue两项,以冒号分隔;[ ]中包含条件类型、keyvalue三项,以逗号分隔,元素key之前使用$字符表示变量;

2.下表内的字符都必须进行转义:

真实字符

转义后的字符

反斜杠(\)

\\

美元符号($)

\$

退格

\b

换页

\f

换行

\n

回车

\r

水平制表

\t

垂直制表

\v

所有Unicode字符

\uxxxx

 

1.3、基于浏览器表单上传的Policy与其他方式的StringToSign的异同

基于浏览器表单上传时,匹配条件可以设置为“Starts-With”,即前缀匹配而非精确匹配,因此在上传时适用于更广的场景。


系列文章推荐

OBS API 鉴权实现宝典(上)—签名计算篇

OBS API 鉴权实现宝典(下)—OBS API实战篇


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。