牙叔教程 简单易懂
目标
自己计算签名, 然后用http上传文件
在这个文档中, 有一个计算签名的例子
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>
- 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());
报错
时间过期了, 我们用当前的时间试试
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是
我们把autojs的body改成aaa试试

autojs的body改成了aaa, 可是还是报错签名错误
再抓一遍python的包试试

没有任何区别, 明明一模一样
我是看不出哪里不对, 然后就该干嘛干嘛, 该吃饭吃饭,
但是脑子里还是对这个问题有各种猜想,
有时间了就试试猜想, 然后就蒙对了
不用oss的sdk, 用http就可以上传文件了

测试环境
手机: Mi 11 Pro
Android版本: 12
Autojs版本: 9.1.20
名人名言
思路是最重要的, 其他的百度, bing, stackoverflow, github, 安卓文档, autojs文档, 最后才是群里问问 --- 牙叔教程
声明
部分内容来自网络 本教程仅用于学习, 禁止用于其他用途