You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
2.4 KiB
96 lines
2.4 KiB
import hashlib
|
|
import hmac
|
|
from urllib.parse import quote
|
|
|
|
|
|
def sha1_hex(data: str) -> str:
|
|
return hashlib.sha1(data.encode("utf-8")).hexdigest()
|
|
|
|
|
|
def hmac_sha1_hex(key: bytes, msg: str) -> str:
|
|
return hmac.new(key, msg.encode("utf-8"), hashlib.sha1).hexdigest()
|
|
|
|
|
|
def canonical_kv(data: dict):
|
|
"""
|
|
等价于 JS:
|
|
D.obj2str(obj, true)
|
|
"""
|
|
items = []
|
|
for k in sorted(data.keys()):
|
|
key = quote(str(k).lower(), safe='')
|
|
val = quote(str(data[k]), safe='')
|
|
items.append(f"{key}={val}")
|
|
return "&".join(items)
|
|
|
|
|
|
def canonical_key_list(data: dict):
|
|
"""
|
|
等价于 JS:
|
|
y(obj, true).join(";").toLowerCase()
|
|
"""
|
|
return ";".join(sorted([k.lower() for k in data.keys()]))
|
|
|
|
|
|
def get_auth(params: dict):
|
|
secret_id = params.get("SecretId")
|
|
secret_key = params.get("SecretKey")
|
|
method = (params.get("Method") or params.get("method") or "get").lower()
|
|
query = params.get("Query") or {}
|
|
headers = params.get("Headers") or {}
|
|
pathname = params.get("Pathname") or ""
|
|
use_raw_key = params.get("UseRawKey", False)
|
|
key_time = params.get("KeyTime")
|
|
|
|
if not secret_id:
|
|
raise ValueError("missing param SecretId")
|
|
if not secret_key:
|
|
raise ValueError("missing param SecretKey")
|
|
|
|
# ===== 处理 Path =====
|
|
if not use_raw_key:
|
|
if not pathname.startswith("/"):
|
|
pathname = "/" + pathname
|
|
|
|
# ===== Canonical 处理 =====
|
|
header_list = canonical_key_list(headers)
|
|
param_list = canonical_key_list(query)
|
|
|
|
header_str = canonical_kv(headers)
|
|
param_str = canonical_kv(query)
|
|
|
|
# ===== HttpString =====
|
|
http_string = "\n".join([
|
|
method,
|
|
pathname,
|
|
param_str,
|
|
header_str,
|
|
""
|
|
])
|
|
|
|
http_sha1 = sha1_hex(http_string)
|
|
|
|
# ===== StringToSign =====
|
|
string_to_sign = "\n".join([
|
|
"sha1",
|
|
key_time,
|
|
http_sha1,
|
|
""
|
|
])
|
|
|
|
# ===== 计算签名 =====
|
|
sign_key = hmac_sha1_hex(secret_key.encode(), key_time)
|
|
signature = hmac_sha1_hex(sign_key.encode(), string_to_sign)
|
|
|
|
# ===== 拼接 Authorization =====
|
|
auth = "&".join([
|
|
"q-sign-algorithm=sha1",
|
|
f"q-ak={secret_id}",
|
|
f"q-sign-time={key_time}",
|
|
f"q-key-time={key_time}",
|
|
f"q-header-list={header_list}",
|
|
f"q-url-param-list={param_list}",
|
|
f"q-signature={signature}"
|
|
])
|
|
|
|
return auth
|