最近由某些原因,需要下载上古时代的文件,结果找出来的链接要么失效、要么龟速。
然后就想到了用网盘的秒传功能来帮我找文件。
其实这方法在阿里云盘上线的早期已经试过,是可以正常用的,不过后来接口加了密,就没继续跟进了。
这次玩的是天翼云盘,毕竟这个是真的不限速!
话不多说,直接开干。
打开F12,找一个可以被秒传的文件,上传
很容易观察到秒传调用接口分两步:
根据后来结论得出:initMultiUpload主要是向后台申请空间(因为可能空间不足,也可能每日上传数据量超过上限),申请成功后,会返回一个uploadid,然后再调用commitMultiUploadFile填上这个uploadid来上传。
可以看到GET请求的参数不可读,已经被加密,所以需要定位加解密算法。
XHR断点勾上,上传。
直接断下来了,代码逻辑非常清晰,就是涉及的算法有点多
其中s = n("xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx")
相当于一个GUID生成器
其中c = n("xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx").slice(0, 16 + 16 * Math.random() | 0)
就是个随机串生成器,这里生成出来的c
值将会被当作AES的key来使用,后面RSA算法加密的就是这个c
其中i.default.AES.encrypt
就是AES(PKCS7填充模式)
其中b.encrypt
就是RSA加密再套一层base64
接下来实现这些算法,由于我只会C艹,所以这里用C艹来实现了。
毫秒时间戳:
AES(调用openssl),注意这里要用PKCS7填充:
HMACSHA1:
RSA:
Base64:
噢对了,还有两个重要的值:
RSA公钥来源:
sessionKey来源:
这俩值随便抓一下,能用几个小时。
parentFolderId=-15
这是个固定的文件夹"我的文档"的ID,每个用户都有且无法删除。想用自建的文件夹就稍微麻烦点。
c
就是上面随机生成的c
值,是个字符串,直接传进去就行
加密结果转成16进制字符串后就是GET参数中的params
随机生成一个GUID填入即可
毫秒级时间戳
PkId与RSA公钥是在同一个接口里拿到的,一定要配套使用才行
SessionKey
来自/api/portal/v2/getUserBriefInfo.action
接口
Date
毫秒级时间戳,保持与X-Request-Date
相同
params
就是GET参数中的params
c
就是上面随机生成的c
值
结果转换成16进制字符串后填写到Signature就行
注意外层有个base64
加密算法同上,不再赘述
成功!仅通过文件的MD5+filesize完整了文件的秒传。
这里也提醒大家,保护好自己的文件信息,可能一张截图就会导致了你的文件不小心被泄露!
https:
/
/
upload.cloud.
189.cn
/
person
/
initMultiUpload
https:
/
/
upload.cloud.
189.cn
/
person
/
commitMultiUploadFile
https:
/
/
upload.cloud.
189.cn
/
person
/
initMultiUpload
https:
/
/
upload.cloud.
189.cn
/
person
/
commitMultiUploadFile
#ifdef _WIN32
#include <sys/timeb.h>
static
uint64_t
__timestamp()
{
struct
timeb rawtime;
ftime(&rawtime);
return
rawtime.
time
* 1000 + rawtime.millitm;
}
#else
#include <sys/time.h>
static
uint64_t
__timestamp()
{
struct
timeval now = {0};
gettimeofday(&now, NULL);
unsigned
long
long
u = now.tv_sec;
u *= 1000;
u += now.tv_usec / 1000;
return
u;
}
#endif
#ifdef _WIN32
#include <sys/timeb.h>
static
uint64_t
__timestamp()
{
struct
timeb rawtime;
ftime(&rawtime);
return
rawtime.
time
* 1000 + rawtime.millitm;
}
#else
#include <sys/time.h>
static
uint64_t
__timestamp()
{
struct
timeval now = {0};
gettimeofday(&now, NULL);
unsigned
long
long
u = now.tv_sec;
u *= 1000;
u += now.tv_usec / 1000;
return
u;
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 5天前
被iaoedsz2018编辑
,原因: 标题修改