OBS API 鉴权实现宝典(中)—POST签名计算
OBS服务支持基于浏览器的POST上传对象请求,此类请求的签名信息通过表单的方式上传。POST上传对象的流程主要如下:
首先,创建一个安全策略,指定请求中需要满足的条件,比如:桶名、对象名前缀;
然后,创建一个基于此策略的签名,需要签名的请求表单中必须包含有效的signature和policy;
最后,创建一个表单将对象上传到桶中。
1、基于浏览器上传的表单中携带签名
官网链接:https://support.huaweicloud.com/api-obs/obs_04_0012.html
1.1、签名的计算原理和计算方法
原理图示
计算方法
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
对象ACL:public-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. # Policy的Base64编码
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可以支持 { } 和 [ ] 两种方式,{ }中包含表单元素的key和value两项,以冒号分隔;[ ]中包含条件类型、key、value三项,以逗号分隔,元素key之前使用$字符表示变量;
2.下表内的字符都必须进行转义:
真实字符 |
转义后的字符 |
反斜杠(\) |
\\ |
美元符号($) |
\$ |
退格 |
\b |
换页 |
\f |
换行 |
\n |
回车 |
\r |
水平制表 |
\t |
垂直制表 |
\v |
所有Unicode字符 |
\uxxxx |
1.3、基于浏览器表单上传的Policy与其他方式的StringToSign的异同
基于浏览器表单上传时,匹配条件可以设置为“Starts-With”,即前缀匹配而非精确匹配,因此在上传时适用于更广的场景。
【系列文章推荐】:
- 点赞
- 收藏
- 关注作者
评论(0)