前言
在js逆向过程中,大多数网站都会对发送到服务器的数据进行加密,而我们要模拟浏览器请求,必须要明白这些数据是干什么的,了解加密方式的特征可以让我们更快知道加密方式,定位加密函数,节省大量时间
博主的博客网站刚开通,所以文章同步更新
欢迎访问:Starrism.top
加密
单向加密(MD系列 sha系列)
指只能加密数据而不能解密数据,这种加密方式主要是为了保证数据的完整性,常见的加密算法有MD5、sha系列等(位于python内置的hashlib模块中)
MD5
MD系列的加密方式主要有MD5、MD4与MD2,但是爬虫中主要遇见的都是MD5,特征:
- 位数只有16位,32位,40位,无论明文数据有多长加密后的长度都是不变的
- 而且数据都是16进制的,最大值不会超过f
- MD5加密函数会出现的默认key:1732584193、271733879在逆向时会节省不少时间
对于未被魔改过的MD5,可记住一些常见的MD5加密后的密文,可对逆向节省时间
如在进行模拟登陆的时候可输入密码为123456
我们只需记住16位前两位是49,32位前两位是E10,就可以很快分辨出这是MD5加密
注意:有些网站可能对原始明文进行取盐操作,需要注意识别
实现:
from hashlib import md5, sha1
test = md5()
test.update("123456".encode())
print(test.hexdigest()) # e10adc3949ba59abbe56e057f20f883e
sha1
sha系列的加密方式主要有sha1、sha256与sha512
- 它们分别为40位,64位,128位
- 也是16进制密文,最大值不会超过f
- 可以向MD5一样记住一些常见的值
实现:
from hashlib import md5, sha1
test = sha1()
test.update("123456".encode())
print(test.hexdigest()) # 7c4a8d09ca3762af61e59520943dc26494f8941b
对称加密(DES、AES)
指数据加密和解密使用相同的秘钥,这种加密方式主要是为了保证数据的机密性,常见的加密算法有DES、AES(位于python第三方库pycrytodomex中)。
AES
AES的加密是用密钥对明文加密为16进制/base64密文,密文长度随着明文增加而增加,有mode和padding的区别,如ECB模式就不需要iv
AES因为密钥的不同,密文也不同,无需记住常见加密,可对js中搜索mode :,padding :等关键词来确定是否为AES加密(当然得是没有混淆的js)
实现:
import base64
from Cryptodome.Cipher import AES
# 需要补位,str不是16的倍数那就补足为16的倍数
def add_to_16(value):
while len(value) % 16 != 0:
value += '\0'
return str.encode(value)
# 加密方法
def aes_encrypt(key, t, iv):
aes = AES.new(add_to_16(key), AES.MODE_CBC, add_to_16(iv)) # 初始化加密器
encrypt_aes = aes.encrypt(add_to_16(t)) # 先进行 aes 加密
encrypted_text = str(base64.encodebytes(encrypt_aes), encoding='utf-8') # 执行加密并转码返回 bytes
return encrypted_text
# 解密方法
def aes_decrypt(key, t, iv):
aes = AES.new(add_to_16(key), AES.MODE_CBC, add_to_16(iv)) # 初始化加密器
base64_decrypted = base64.decodebytes(t.encode(encoding='utf-8')) # 优先逆向解密 base64 成 bytes
decrypted_text = str(aes.decrypt(base64_decrypted), encoding='utf-8').replace('\0', '') # 执行解密密并转码返回str
return decrypted_text
if __name__ == '__main__':
secret_key = '12345678' # 密钥
text = '123456' # 加密对象
iv = secret_key # 初始向量
encrypted_str = aes_encrypt(secret_key, text, iv)
print('加密字符串:', encrypted_str) # PUuf+EzDHshBewHOKqUi9w==
decrypted_str = aes_decrypt(secret_key, encrypted_str, iv)
print('解密字符串:', decrypted_str) # 123456
DES
类似与AES
非对称加密(RSA)
会产生公钥和私钥,公钥在客户端,私钥在服务端。公钥用于加密,私钥用于解密。
这种加密方式基本不可能被破解,主要用于身份验证等方面,常见的加密算法有DSA、RSA(位于python第三方模块rsa中)。
实现:
import rsa
def rsa_encrypt(pu_key, t):
# 公钥加密
rsa = rsa.encrypt(t.encode("utf-8"), pu_key)
return rsa
def rsa_decrypt(pr_key, t):
# 私钥解密
rsa = rsa.decrypt(t, pr_key).decode("utf-8")
return rsa
if __name__ == "__main__":
public_key, private_key = rsa.newkeys(512) # 生成公钥、私钥
print('公钥:', public_key)
print('私钥:', private_key)
text = '123456' # 加密对象
encrypted_str = rsa_encrypt(public_key, text)
print('加密字符串:', encrypted_str)
decrypted_str = rsa_decrypt(private_key, encrypted_str)
print('解密字符串:', decrypted_str)
编码
编码不能算是加密,但是也能有一些混淆作用,如bsae64
,16进制
转换等都有明显的特征
Base64
在参数传输的过程中经常遇到的一种情况:使用全英文的没问题,但一旦涉及到中文就会出现乱码情况。与此类似,网络上传输的字符并不全是可打印的字符,比如二进制文件、图片等。Base64的出现就是为了解决此问题,它是基于64个可打印的字符来表示二进制的数据的一种方法
特征为A-Z,a-z,0-9,+,=,_,且大概率结尾是=,可在js中搜索btoa验证加密
实现:
import base64
def base64_encode(text):
encode_data = base64.b64encode(text.encode())
return encode_data
def base64_decode(encode_data):
decode_data = base64.b64decode(encode_data)
return decode_data
if __name__ == '__main__':
text = '123456'
encode_data = base64_encode(text)
decode_data = base64_decode(encode_data)
print('Base64 编码:', encode_data) # b'MTIzNDU2'
print('Base64 解码:', decode_data) # b'123456'