JS逆向中特殊RSA加密密钥
在对某个网站的接口进行逆向的时候发现其使用了RSA加密,但是其中的密钥生成方式比较特殊。
JS部分代码如下所示:
var f = new n.jsbn.BigInteger("9E08DA9CB4357388754D6AFF8ED0E1A9C46CD927291ACBC26C08E97E80BC8FFA1F9ABD31CDE9587785183A51********************************************************",16)
//密钥部分做了脱敏
, u = new n.jsbn.BigInteger("10001",16)
, C = n.pki.rsa.setPublicKey(f, u)
, y = function(l) {
var D = C.encrypt(l, "RSA-OAEP", {
md: n.md.sha1.create(),
mgf1: {
md: n.md.sha1.create()
}
});
return n.util.encode64(D);
}
可以看到这里加密用到的公钥比较特殊,与我们常见的标准公钥格式并不一致,标准的公钥是英文大小写+数字+特殊符号,而这里的密钥格式为大写字母+数字。因为格式不对是无法直接按照常规的RSA加密来实现的。
经过一番查找资料后,才知道这是使用模数和指数
来生成公钥,进而进行RSA加密的过程。其中9E08DA9CB4357388754D6AF
开头的这部分是模数的16进制形式,而10001则是指数65537的16进制形式。关于模数和指数生成RSA密钥的具体实现可以自行搜索研究,而我们目前要做的是使用python实现这个加密,也就是使用cryptography
这个模块来完成模数和指数生成密钥并且加密的过程。
所以以上JS代码可以使用以下python代码实现:
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import rsa
import base64
need_encrypt_str = "test"
# 模数
modulus_hex = "9E08DA9CB4357388754D6AFF8ED0E1A9C46CD927291ACBD****************"
modulus = int(modulus_hex, 16)
# 公钥
public_key = rsa.RSAPublicNumbers(
e=65537, # 公钥指数
n=modulus
).public_key(default_backend())
# 使用RSA-OAEP填充方案和SHA-256哈希函数加密数据
encrypted_data = public_key.encrypt(
need_encrypt_str.encode("utf-8"),
padding.OAEP(
mgf=padding.MGF1(algorithm=hashes.SHA1()),
algorithm=hashes.SHA1(),
label=None
)
)
encrpted_str = base64.b64encode(encrypted_data).decode("utf-8")
print(encrpted_str)