T23非对称加密

一:抓包分析

还是老一套,翻页查看加密参数,请求题加密参数为dataverify,请求头加密参数为x-auth-key,x-signature

image-20260511153108364

image-20260511153150006

二:加密参数分析

全局搜索x-signature

image-20260511153705235

image-20260511153936753

可以看到加密参数都在这里

1、X-Auth-Key

直接进到u函数

image-20260511155033673

看到setPublicKey,初步认定为RSA加密,直接用如上的public key生成一个加密函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import rsa
import base64

PUBLIC_KEY_PEM = """-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1vKwZUIv7pgpJUXXPpDlD4+VE
on3a0ANOrNmqAESrcGfkmYzDCo2JeuYezhBGjBNjwVmSct/Y3BBOCRGT2bvtCJGd
S12RMvHbFcdbwS/Adh48+rhLiMNYXLm+7pI3e2k6TlScxKa7EeeZpVtew/Cv5z6o
l0llNPp6BdqAlOa8DwIDAQAB
-----END PUBLIC KEY-----
"""


def rsa_encrypt(data, encoding='utf-8') -> str:
"""
与 JavaScript crypto.publicEncrypt 完全一致:
- 输入: str 或 bytes
- 对字符串使用 UTF-8 编码后加密(不预先做 base64)
- PKCS#1 v1.5 填充
- 返回 base64 密文字符串
"""
if isinstance(data, str):
plaintext = data.encode(encoding)
elif isinstance(data, bytes):
plaintext = data
else:
raise TypeError(f"data 必须是 bytes 或 str,当前类型为 {type(data)}")

# 加载公钥
pub_key = rsa.PublicKey.load_pkcs1_openssl_pem(PUBLIC_KEY_PEM.encode())

# 检查长度(RSA 1024位最多加密117字节)
if len(plaintext) > 117:
raise ValueError(f"明文过长,最多 117 字节,当前 {len(plaintext)} 字节")

# 加密(使用 PKCS#1 v1.5 填充)
ciphertext = rsa.encrypt(plaintext, pub_key)

# 返回 Base64 编码的密文
return base64.b64encode(ciphertext).decode('utf-8')
2、X-Signature

image-20260511200339196

X-Signature如图所示计算得来,也就是通过私钥签名,然后使用SHA256加密输出base64格式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import base64
from Crypto.PublicKey import RSA
from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA256

def rsa_sign(data: str) -> str:
private_key_pem = """-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQC1vKwZUIv7pgpJUXXPpDlD4+VEon3a0ANOrNmqAESrcGfkmYzD
Co2JeuYezhBGjBNjwVmSct/Y3BBOCRGT2bvtCJGdS12RMvHbFcdbwS/Adh48+rhL
iMNYXLm+7pI3e2k6TlScxKa7EeeZpVtew/Cv5z6ol0llNPp6BdqAlOa8DwIDAQAB
AoGAS0GaWI9AsFAFEXBgoz/jkMf14DKTgEFEJVexeNLMnNuawhCNuBSOIMCaO2Zk
WfpWaygdUeYs6M3UGKRruXhf92g/BRmJK5FzR0kWW4qw6WwlYob3TPc3c9MFOjmp
VtWQ0VSeEPrnBNoQRccKl0dGBnToHGuV+KEuKx8oWZc/JM0CQQDH/cvlx0BKz2zN
6PM8FidAvc+Wgon8YW81KJgC7iJIrK9FOpctOE3L1pdF7guOQNVGRqN4HCIgLfHE
cqxWJKJtAkEA6KIkwHe/Q23uWH5GP8DHtVkLVfohTumYkpb0rk05EYQ0dsWSNzWH
XDH/kD6ayNq+fscnS8g+59onzvfhJ0bq6wJBAKNFkDEHenWY4js481sauvEgBVnb
OMvSv/emLHQ39cVfNbhPHRzN2rWPe/CbZtO8GmJFSS/FyBZ9a+P1uryZLAECQAaw
ApZ12s25b0yj9KkIhbU05hqGokZ+eKBeLpKELcvPHSL88wMbStTfqxUed5ymjStf
1kVbcFOB9fsBLTvP0hkCQFCON0l1VjFli+vqfN0lypgIqCf85V6FZFN19creGCCd
76pX/X2FIBbUSDN1z48SM5I/RKdCkTx7FY+509q2Mek=
-----END RSA PRIVATE KEY-----"""
try:
key = RSA.import_key(private_key_pem)
h = SHA256.new(data.encode('utf-8'))
signature = pkcs1_15.new(key).sign(h)
return base64.b64encode(signature).decode('ascii')
except Exception:
return ""

image-20260511201646094

image-20260511201700677

一致

3、data

实际为u(s + "_param")

4、verify

实际就是

1
2
3
var i = function(e) {
return CryptoJS.HmacSHA256(e, "dsa_secret_key_2025").toString()
}(s)

直接用t21题的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import hashlib
import hmac
from typing import Union

def hmac_custom(key: Union[bytes, str], data: Union[bytes, str], algorithm=hashlib.sha256) -> str:
"""
使用指定哈希算法计算 HMAC。
参数:
key: 密钥
data: 消息
algorithm: 哈希构造函数(如 hashlib.sha256, hashlib.sha1 等)
返回:
十六进制字符串表示的 HMAC 值
"""
if isinstance(key, str):
key = key.encode('utf-8')
if isinstance(data, str):
data = data.encode('utf-8')
return hmac.new(key, data, algorithm).hexdigest()

image-20260511202108058

image-20260511202122732

一致

三:编码与验证

image-20260511205120376

更多内容也在公众号更新:码字的秃猴

tuhou