[md]# 先抓包看上传流程如图
大致上传流程
- 图1用自己cookie 或者token拿到authorization access_key_id secret_access_key,等参数
- 图2 通过图1返回的参数请求地址 拿到一个图片地址
- 图3 请求图2返回地址进行上传
目标
图二有个Signature经测试是上传所需要的必须签名,下面我们来看下是怎么生成的。
拖进jadx查看代码
搜索关键字AWS4-HMAC-SHA256找到关键代码
public Map<String, String> getHeaders() {
ChangeQuickRedirect changeQuickRedirect2 = changeQuickRedirect;
if (PatchProxy.isEnable(changeQuickRedirect2)) {
PatchProxyResult proxy = PatchProxy.proxy(PatchProxy.getEmptyArgs(), this, changeQuickRedirect2, false, 4);
if (proxy.isSupported) {
return (Map) proxy.result;
}
}
String calculateSignature = calculateSignature(prepareStringToSign(prepareCanonicalRequest()));
if (calculateSignature == null) {
if (this.debug) {
System.out.println(O.C("##Signature:\n", calculateSignature));
return null;
}
return null;
}
HashMap hashMap = new HashMap(0);
for (Map.Entry<String, String> entry : this.awsHeaders.entrySet()) {
hashMap.put(entry.getKey(), entry.getValue());
}
hashMap.put("Authorization", buildAuthorizationString(calculateSignature));
if (this.debug) {
System.out.println(O.C("##Signature:\n", calculateSignature));
System.out.println("##Header:");
for (Map.Entry entry2 : hashMap.entrySet()) {
PrintStream printStream = System.out;
new StringBuilder();
printStream.println(O.C((String) entry2.getKey(), " = ", (String) entry2.getValue()));
}
System.out.println("================================");
}
return hashMap;
}
private String calculateSignature(String str) {
ChangeQuickRedirect changeQuickRedirect2 = changeQuickRedirect;
if (PatchProxy.isEnable(changeQuickRedirect2)) {
PatchProxyResult proxy = PatchProxy.proxy(new Object[]{str}, this, changeQuickRedirect2, false, 3);
if (proxy.isSupported) {
return (String) proxy.result;
}
}
try {
return bytesToHex(SHA256UseMac(getSignatureKey(this.secretAccessKey, this.currentDate, this.regionName, this.serviceName), str));
} catch (Exception unused) {
return null;
}
}
private String prepareStringToSign(String str) {
ChangeQuickRedirect changeQuickRedirect2 = changeQuickRedirect;
if (PatchProxy.isEnable(changeQuickRedirect2)) {
PatchProxyResult proxy = PatchProxy.proxy(new Object[]{str}, this, changeQuickRedirect2, false, 2);
if (proxy.isSupported) {
return (String) proxy.result;
}
}
new StringBuilder();
String C = O.C("AWS4-HMAC-SHA256\n", this.xAmzDate, "\n");
new StringBuilder();
String C2 = O.C(C, this.currentDate, "/", this.regionName, "/", this.serviceName, "/aws4_request", "\n");
new StringBuilder();
String C3 = O.C(C2, generateHex(str));
if (this.debug) {
System.out.println(O.C("##String to sign:\n", C3));
}
return C3;
}
private String calculateSignature(String str) {
ChangeQuickRedirect changeQuickRedirect2 = changeQuickRedirect;
if (PatchProxy.isEnable(changeQuickRedirect2)) {
PatchProxyResult proxy = PatchProxy.proxy(new Object[]{str}, this, changeQuickRedirect2, false, 3);
if (proxy.isSupported) {
return (String) proxy.result;
}
}
try {
return bytesToHex(SHA256UseMac(getSignatureKey(this.secretAccessKey, this.currentDate, this.regionName, this.serviceName), str));
} catch (Exception unused) {
return null;
}
}
通过查看代码可以了解流程
prepareCanonicalRequest方法用于构建规范请求字符串。
prepareStringToSign方法用于生成待签名字符串。
calculateSignature方法内部调用了SHA256UseMac
getHeaders方法最终将生成的签名加入到请求头中,并返回。
总结
1准备签名信息:包括请求方法(GET、POST等)、请求URI、查询字符串参数、请求头部信息(如Host、x-amz-date等),以及请求体(对于POST请求)。
2创建规范请求:将上述信息按照AWS的规定格式组合成一个规范请求字符串。
3构造待签名字符串:这一步涉及到将规范请求的哈希值、请求日期、服务区域、服务名称等信息按照特定格式组合,形成待签名字符串。
4计算签名:
使用AWS的密钥生成算法(HMAC-SHA256)计算派生签名密钥。
使用派生的签名密钥对待签名字符串进行签名,生成最终的签名值。
添加签名到请求:将生成的签名值添加到请求的授权头部或查询字符串参数中,完成请求的签名过程。
结果
python复现一下
侵权删!