牙叔教程 简单易懂
目标
自己计算签名, 然后用http上传文件
在Header中包含签名
在这个文档中, 有一个计算签名的例子
import hmac import hashlib import base64 h = hmac.new("Q0YehC6ZyugWfjod5y8Rcqrc1y****".encode('utf-8'), "PUT\nODBGOERFMDMzQTcxxxzA5QzdFNUYzMDQxNEM\ntext/html\nThu, 17 Nov 2005 18:49:58 GMT\nx-oss-meta-magic:abracadabra\nx-oss-meta-author:foo@example.com\n/oss-example/nelson".encode('utf-8'), hashlib.sha1) signature = base64.encodestring(h.digest()) print(signature)
这是用python2计算的,
计算结果是
al2vHOlTWQdQtM6oqJAEZh7d****
我们用python2计算一下看是不是
结果不一样子, 搞个锤子
把python代码修改为autojs代码
同时也可以, 参考android 和 java的sdk;
我们只添加必备字段
- AccessKeyId LTAI5t7iuxxxUU4ApjG
- AccessKeySecret GNrlNLxxxxosQgxuu
- VERB PUT
- \n
- Date Sun, 22 Nov 2015 08:16:38 GMT 此次操作的时间,Date必须为GMT格式且不能为空。
- CanonicalizedResource /examplebucket/
签名字符串计算公式
Signature = base64(hmac-sha1(AccessKeySecret,VERB + “\n” + Content-MD5 + “\n”+ Content-Type + “\n” + Date + “\n” + CanonicalizedOSSHeaders+ CanonicalizedResource))
我们只留下必备字段
Signature = base64(hmac-sha1(AccessKeySecret,VERB + "\n" + Date + "\n" + CanonicalizedResource))
上面的python代码去掉多余选项改为
import hmac import hashlib import base64 h = hmac.new("LTAI5t7iuNjWdyMkXUU4ApjG".encode('utf-8'), "PUT\nThu, 17 Nov 2005 18:49:58 GMT\n/autojs-study/yashu.txt".encode('utf-8'), hashlib.sha1) signature = base64.encodestring(h.digest()) print(signature)
运行结果
修改为对应的autojs代码
encryptText = "GNrlNLxxxxakxxxgxuu"; VERB = "PUT"; Date = "Thu, 17 Nov 2005 18:49:58 GMT"; CanonicalizedResource = "/autojs-study/yashu.txt"; encryptKey = VERB + "\n" + Date + "\n" + CanonicalizedResource; r = HmacSHA1Encrypt(encryptKey, encryptText);
运行结果
上传文件请求语法
PUT / HTTP/1.1 Host: BucketName.oss-cn-hangzhou.aliyuncs.com Date: GMT Date x-oss-acl: Permission Authorization: SignatureValue <?xml version="1.0" encoding="UTF-8"?> <CreateBucketConfiguration> <StorageClass>Standard</StorageClass> </CreateBucketConfiguration>
公共HTTP头定义
- Authorization
- Content-Length
- Content-Type
- Date
- Host 访问Host值,格式为.oss-cn-hangzhou.aliyuncs.com。
不管怎么调, 就是报签名错误
autojs请求代码
let headers = { "Content-Type": "application/x-www-form-urlencoded", Date: date, Authorization: Authorization, Host: "autojs-study.oss-cn-beijing.aliyuncs.com", }; body = { "yashu.txt": "bbbb", }; body = JSON.stringify(body); let url = "http://autojs-study.oss-cn-beijing.aliyuncs.com"; r = http.request(url, { method: "PUT", body: body, headers: headers, }); log(r.statusCode); log(r.body.string());
响应报错内容
<Code>SignatureDoesNotMatch</Code> <Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
不知道哪里不对, 我觉得我哪里都是按照规则来的,
那么就抓包看看吧
下载一个 wireshark
然后执行python代码, 上传文件
python2 PutObject.py -i LTAI5t7iuxxx4ApjG -k GNrlNLxxxxxSosQgxuu -e oss-cn-beijing.aliyuncs.com -b autojs-study -f localfile.txt -o aliyun3.txt
去oss控制台看看, 文件aliyun3.txt上传成功
快捷键 ctrl + shift + D , 清空wireshark记录, 再次执行python命令, 抓包看看
右击/ 追踪流/ http流
PUT /aliyun3.txt HTTP/1.1 Accept-Encoding: identity Content-Length: 3 Connection: close User-Agent: Python-urllib/2.7 Host: autojs-study.oss-cn-beijing.aliyuncs.com Date: Fri, 03 Jun 2022 08:09:46 GMT Content-Type: application/x-www-form-urlencoded Authorization: OSS LTAI5txxxx4ApjG:hjJHO6yP/mkYfFDpPEUjB1lvIOA= aaa
我们主要关心的是签名,
python的签名计算
def GetSignature(self): print(self.bk) content = "PUT\n\n{0}\n{1}\n/{2}/{3}".format(self.types,self.GetGMT(),self.bk,self.oj) print(content) mac = hmac.new("{0}".format(self.sk),content, sha) Signature = base64.b64encode(mac.digest()) return Signature
我们把content打印出来
PUT application/x-www-form-urlencoded Fri, 03 Jun 2022 08:09:46 GMT /autojs-study/aliyun3.txt
我们用同样的数据计算签名
autojs9支持反引号, 复制黏贴就可以计算签名了, python与autojs计算出来的签名结果是一致的
接下来构造请求
首先是URL
let url = "http://autojs-study.oss-cn-beijing.aliyuncs.com/aliyun3.txt";
然后是拼接 Authorization
Authorization = "OSS " + AccessKeyId + ":" + Signature;
再构造header
let headers = { "Accept-Encoding": "identity", "Content-Length": "3", Connection: "close", "User-Agent": "Python-urllib/2.7", Host: "autojs-study.oss-cn-beijing.aliyuncs.com", Date: "Fri, 03 Jun 2022 08:09:46 GMT", "Content-Type": "application/x-www-form-urlencoded", Authorization: "OSS LTAI5xxxxU4ApjG:hjJHO6yP/mkYfFDpPEUjB1lvIOA=", };
最后是body
body = { "aliyun3.txt": "bbb", }; body = JSON.stringify(body);
构造完成, 发起请求
let url = "http://autojs-study.oss-cn-beijing.aliyuncs.com/aliyun3.txt"; r = http.request(url, { method: "PUT", body: body, headers: headers, }); log(r.statusCode); log(r.body.string());
报错
RequestTimeTooSkewed
时间过期了, 我们用当前的时间试试
function getTime() { return new Date().toGMTString(); }
不出意外, 还是报错, 签名不对
用wireshark抓一下, 手机发送的请求
试了好几个网卡, 都抓不到手机, 在雷电模拟器上运行autojs, 再抓包吧
雷电模拟器抓包的包
之前的python包
PUT /aliyun3.txt HTTP/1.1 Accept-Encoding: identity Content-Length: 3 Connection: close User-Agent: Python-urllib/2.7 Host: autojs-study.oss-cn-beijing.aliyuncs.com Date: Fri, 03 Jun 2022 08:09:46 GMT Content-Type: application/x-www-form-urlencoded Authorization: OSS LTAIxxxxApjG:hjJHO6yP/mkYfFDpPEUjB1lvIOA= aaa
autojs的body是
body = { "aliyun3.txt": "bbb", };
python的body是
aaa
我们把autojs的body改成aaa试试
autojs的body改成了aaa, 可是还是报错签名错误
再抓一遍python的包试试
没有任何区别, 明明一模一样
我是看不出哪里不对, 然后就该干嘛干嘛, 该吃饭吃饭,
但是脑子里还是对这个问题有各种猜想,
有时间了就试试猜想, 然后就蒙对了
不用oss的sdk, 用http就可以上传文件了
测试环境
手机: Mi 11 Pro
Android版本: 12
Autojs版本: 9.1.20
名人名言
思路是最重要的, 其他的百度, bing, stackoverflow, github, 安卓文档, autojs文档, 最后才是群里问问 --- 牙叔教程
声明
部分内容来自网络 本教程仅用于学习, 禁止用于其他用途