揭秘JS逆向:常见加密算法与破解技巧

发布于:2025-08-15 ⋅ 阅读:(17) ⋅ 点赞:(0)

JS逆向

常见的加密算法和解决思路

1. 什么是js逆向

JS逆向是指通过分析和破解JavaScript代码,获取反爬措施的规则和实现方式,从而绕过反爬措施,实现爬虫的抓取。JS逆向需要具备一定的JavaScript编程能力和代码分析能力,对于爬虫开发者来说是一项高级的技能。

需要注意的是,进行JS逆向可能会涉及到法律风险和道德问题,因此在进行爬虫开发时,应该遵守相关法规和道德规范,避免侵犯他人的合法权益。

2. 为什么要学习js逆向

现在的网页越来越多,使用JavaScript来动态加载内容或进行数据加密,传统的静态爬虫无法直接获取这些数据。掌握JS逆向技术可以绕过这些限制,获取所需的数据。

2.1 如何使用js逆向

实现步骤:

  • 分析网页请求:使用浏览器开发者工具(如Chrome)查看网络请求,找到数据加载的API接口。

  • 定位关键JS代码:通过断点调试、搜索关键词等方式,找到生成加密参数或动态数据的JavaScript代码。

  • 理解逻辑:分析JavaScript代码的逻辑,尤其是加密算法、参数生成方式等。

  • 模拟执行:使用Python的exe.js、PyExe.js等库,或者直接使用Node.js来模拟执行JavaScript代码,生成所需的参数。

  • 构造请求:将生成的参数加入到HTTP请求中,获取数据。

使用工具:

  • 浏览器开发者工具:用于调试和分析JavaScript代码。

  • Python库:requests、exe.js、PyExe.js等。

  • Node.js:用于执行复杂的JavaScript代码。

2.2 什么情况下使用js逆向
  • 动态数据加载:某些网页通过JavaScript动态加载数据,直接请求HTML无法获取。

  • 加密参数:某些API接口需要加密参数(如Token、签名sign等),这些参数通过JavaScript生成。

  • 反爬虫机制:如验证码、IP封禁、请求频率限制等,通过js逆向可以绕过这些限制。

js逆向的流程

  1. 分析目标网站的反爬措施:使用浏览器开发者工具或网络抓包工具,分析目标网站的JavaScript代码和网络请求数据,了解反爬措施的实现方式和规则。常见的反爬措施包括动态渲染、异步加载、验证码、IP限制等。

  2. 理解和分析JavaScript代码:使用代码编辑器或开发者工具等工具,分析网站的JavaScript代码,了解其运行原理、代码结构和实现方式。这可以帮助你找到反爬措施的规则和实现方式,从而更好地绕过它们。

  3. 绕过反爬措施:根据分析结果,采用相应的技术和方法绕过反爬措施。比如:

    • 对于动态渲染的网页,可以使用无头浏览器(如Selenium)模拟浏览器的操作

    • 对于异步加载的网页,可以使用JavaScript库(如Puppeteer)模拟浏览器的异步请求

    • 对于验证码的网站,可以使用打码平台或自动识别技术(如OCR)来识别验证码

  4. 调试和优化:进行调试和优化,确保爬虫程序能够稳定地运行,并且能够在反爬措施更新后及时进行适配。

js逆向的环境搭建

  • 安装node.js

    • npm init -y 初始化项目

    • npm install

  • 安装Crypto模块

    • npm install Crypto

    • npm install Crypto-JS


3. js常见加密算法

3.1 Base64算法

  • base64是一种用64个字符来表示任意二进制数据的方法。base64使用 A-Z a-z 0-9 + / 这64个字符实现对数据的加密。

  • 变种 base64 编码:将+替换为 - /替换为,避免在 url 中产生歧义

为什么会有Base64编码因为有些网络传送渠道并不支持所有的字节,例如传统的邮件只支持可见字符的传送,像ASCII码的控制字符就不能通过邮件传送。这样用流就受到了很大的限制,比如图片二进制流的每个字节不可能全部是可见字符,所以就传送不了。最好的方法就是在不改变传统协议的情况下,做一种扩展方案来支持二进制文件的传送。把不可打印的字符也能用可打印字符来表示,问题就解决了。Base64编码应运而生,Base64就是一种基于64个可打印字符来表示二进制数据的表示方法。

base64编码特征:

  1. 输出一定是4的整数倍

  2. 一次处理3个字节,通过一个映射关系将其转为4个字节,所以编码后的数据大小会膨胀约33%

  3. 如果数据不足3字节,会用"="进行填充,编码结果就会以等于号结尾

用途:

  1. 在只能存在字符的情况下嵌入二进制数据

  2. 避免特殊字符导致问题

  3. 对数据进行伪加密

from base64 import b64encode, b64decode
b64encode("HD") # 编码,js 中为 btoa(浏览器内置,高版本 node 内置)
b64decode("SEQ=") # 解码,js 中为 atob
​
# 变种 base64 编码:将 + 替换为-, /替换为,避免在 url 中产生歧义
import base64
​
"""将字符串转换成base64编码"""
# 定义要编码的原始字符串
string = "https://www.baidu.com"
# 将字符串转换为UTF-8编码的二进制数据(bytes对象)
temp_b = string.encode("utf-8")
# 打印二进制数据
print(temp_b)
​
# 对二进制数据进行Base64编码
content_b = base64.b64encode(temp_b)
# 打印Base64编码的二进制结果
print(content_b)
​
# 将Base64编码的二进制结果转换为UTF-8字符串格式
str_result = content_b.decode('utf-8')
# 打印最终的Base64字符串
print(str_result)
​
"""将Base64编码还原为字符串"""
# 定义Base64编码的字符串
str_result = "aHR0CHM6Ly93d3cuYmFpZHUuY29t"
# 先进行Base64编码得到二进制数据,再转换为UTF-8字符串
my_str = base64.b64decode(str_result).decode("utf-8")
# 打印还原后的原始字符串
print(my_str)
​
"""处理base64编码的图片"""
# 包含Base64图片数据的Data URL
src = "data:image/jpg;base64,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"
​
# 切割Data URL字符串,获取逗号后的Base64数据部分
image_data = src.split(',')[1]
# 对Base64图片数据进行解码,得到原始二进制数据
image = base64.b64decode(image_data)
# 打印二进制图片数据
print(image)
# 使用with语句安全地打开文件,'wb'表示二进制写入模式
with open('验证码.jpg','wb') as f:
    # 将解码后的二进制图片数据写入文件
    f.write(image)

3.2 MD5算法

MD5是一种被广泛使用的线性散列算法,可以产出一个128位(16字节)的散列值(hash value),用于确保信息传输完整的一致性。且MD5加密之后产生的是一个固定长度(32位或16位)数据。

参考网址:

补充: 为了提高密码的安全性,一般会在密码后面加上一个随机数或者是时间戳,这个随机数或者是时间戳我们一般称之为盐。

MD5算法原理:是将输入的消息分成512位的数据块,每个数据块再分成16个32位的小块,然后通过一系列的运算和非线性函数,对每个小块进行处理,最终得到一个128位的哈希值。由于MD5算法的设计,即使输入的消息只有微小的变化,也会导致输出的哈希值发生巨大的变化,因此可以用来验证数据的完整性和真实性。

MD5算法的用途:

  • 数据完整性验证:通过比较两个文件的MD5值,可以判断它们是否相同

  • 密码加密:将用户的密码进行MD5加密后,可以保证用户密码的安全性

  • 数字签名:保证数据完整性和真实性的技术

  • 安全访问控制:生成安全访问控制的密钥

MD5哈希算法特征:

  1. 输出固定为32位十六进制(0-9,a-f)

  2. 计算过程分块处理(512位/块)

  3. 不可逆运算,无法通过哈希值反推原始数据

  4. 存在长度扩展攻击和碰撞漏洞

用途:

  1. 数据完整性校验(文件传输验证)

  2. 作为数据唯一性指纹(缓存键生成)

  3. 系统密码存储(需配合加盐)

  4. 数字证书校验(逐步被SHA替代)

# 导入hashlib模块,用于实现常见的加密算法
import hashlib
import os
​
"""对字符串进行MD5加密"""
def md5_str(text):
    # 创建md5加密对象
    md = hashlib.md5()
    # 注意:需要将字符串编码为bytes类型才能进行加密
    # 更新加密对象的数据(UTF-8是推荐的标准编码方式)
    md.update(text.encode('utf-8'))
    # 获取十六进制格式的加密结果
    # hexdigest()返回长度为32的十六进制字符串
    return md.hexdigest()
​
# 测试字符串加密
original_str = "Hello,世界!"
encrypted_str = md5_str(original_str)
print("原始字符串:", original_str)
print("MD5加密结果:", encrypted_str)
​
"""对文件进行MD5加密"""
def md5_file(file_path):
    # 创建md5加密对象
    md = hashlib.md5()
    # 使用二进制读模式打开文件 ("rb")
    # with语句可以自动处理文件关闭,适合文件操作
    with open(file_path, 'rb') as f:
        # 分块读取文件内容,适合大文件处理
        while True:
            # 每次读取4096字节(常用块大小)
            chunk = f.read(4096)
            if not chunk: # 当读取到文件末尾时停止
                break
            md.update(chunk) # 逐块更新加密数据
    return md.hexdigest()
​
# 测试文件加密(假设存在一个test.txt文件)
file_path = 'test.txt'
try:
    file_hash = md5_file(file_path)
    print("\n文件路径:", file_path)
    print("文件MD5:", file_hash)
except FileNotFoundError:
    print(f"\n错误:文件 {file_path} 不存在")
​
"""重要说明"""
# 1. MD5是单向加密算法,无法解密(不可逆)
# 2. MD5存在碰撞漏洞,不适用于安全敏感场景(如密码存储)
# 3. 不同内容的MD5可能相同(碰撞),重要场景推荐使用SHA-256
# 4. 文件MD5常用于验证文件完整性(检测文件是否被篡改)
​
# 验证加密过程(使用标准测试数据)
test_case = "123456"
expected_hash = "e10adc3949ba59abbe56e057f20f883e"
print("\n测试用例验证:")
print("计算结果:", md5_str(test_case))
print("预期结果:", expected_hash)
print("验证通过" if md5_str(test_case) == expected_hash else "验证失败")
​
"""生成随机盐值(推荐至少16字节)"""
def generate_salt(length=16):
    # os.urandom 生成加密安全的随机字节(适合盐值)
    salt_bytes = os.urandom(length)
    # 将二进制盐转为十六进制字符串便于存储
    return salt_bytes.hex()
​
"""带盐值的MD5加密"""
def md5_str_salted(text, salt=None):
    md = hashlib.md5()
    # 若未提供盐值则自动生成(默认16字节随机盐)
    if salt is None:
        salt = generate_salt()
    else:
        # 确保传入的盐是字符串格式(如从数据库读取)
        salt = str(salt)
    # 将盐值与原始文本组合(盐 + 文本)
    salted_text = salt.encode() + text.encode('utf-8')
    md.update(salted_text)
    return md.hexdigest(), salt # 返回哈希值和使用的盐
​
# 测试加盐加密
original_str = "Hello,世界!"
# 场景1:自动生成随机盐
hash1, salt1 = md5_str_salted(original_str)
print(f"加密1 - 盐值: {salt1}")
print(f"加密1 - 哈希: {hash1}\n")
​
# 场景2:使用固定盐(如从数据库读取)
stored_salt = "alb263d465f67890"
hash2, _ = md5_str_salted(original_str, stored_salt)
print(f"加密2 - 固定盐: {stored_salt}")
print(f"加密2 - 哈希: {hash2}\n")
​
# 验证相同文本不同的结果差异
hash3, salt3 = md5_str_salted(original_str)
print(f"加密3 - 新盐: {salt3}")
print(f"加密3 - 哈希: {hash3}")
print("哈希1与哈希3是否不同:", hash1 != hash3) # 应输出True

3.3 DES/DES3/AES算法

DES对称加密,是一种比较传统的加密方式,其加密运算、解密运算使用的是同样的密钥。信息的发送者和信息的接收者在进行信息的传输与处理时,必须共同持有该密钥(称为对称密码),是一种对称加密算法。一般来说加密用的是encrypt()函数,解密用的是decrypt()函数。

AES和DES的区别:

加密后密文长度不同

  • DES加密后密文长度是8的整数倍(但已经不是很安全)

  • DES3对数据进行3次DES加密,比DES安全,但速度和安全性仍慢于AES)

  • AES加密后密文的长度是16的整数倍

安全度不同

  • 一般情况下DES足够安全

  • 如果要求高可以使用AES

DES和AES切换只需要修改CryptoJS.DES => CryptoJS.AES

安装模块: pip install pycryptodome 导入时的模块名称: Crypto

共同特征:

  • 输入明文为二进制数据,输出密文为二进制数据

  • 一般对密文进行base64编码或转为16进制字符串

  • 密码、偏移量也都是二进制数据

DES算法
  • 对称加密:加解密使用相同密码

  • 分组加密:每次处理8字节的明文,输出8字节密文

  • 密钥长度:8字节

  • 偏移量长度:8字节

  • 已经不安全

  • 模式(不同模式存在本质区别):

    • ECB: 需要密钥

    • CBC: 需要密钥(key)、偏移量(iv)

  • 填充 (padding):

    • 明文必须是8字节的整数倍,否则需要进行填充

    • 向原始数据末尾添加额外字节

    • 存在不同的填充方案:

      • pkcs7: 填充了n个字符,填充字符就是\x0n

      • x923: 填充了n个字符,最后一个填充字符就是\x0n,其余的是\x00

      • iso7816: 第一个填充字符为\x80,其余的是\x00

    • 解密时也需要去除填充

from Crypto.Cipher import DES
# 如果明文不是8个字节可以使用填充
from Crypto.Util.Padding import pad, unpad
from base64 import b64decode, b64encode
​
# ECB模式2个参数 CBC 3个参数 还有一个偏移量
# 第一个参数:8个字节的密钥
# 第二个参数:ECB或者CBC模式
# 第三个参数:偏移量
# obj = DES.new("abcd1234".encode(), DES.MODE_ECB)
obj = DES.new("abcd1234".encode(), DES.MODE_CBC, iv="12345678".encode())
# 加密一个中文字4个字节 刚好8个字节
# 如果不够8个字节就需要使用填充
# 填充的话 pkcs7/x923/iso7816 三种模式
# res = obj.encrypt("机密ab".encode())
res = obj.encrypt(pad("机密".encode(), 8))
# res = obj.encrypt(pad("机密".encode(), 8,x923))即可换填充模式,默认是pkcs7
# 对密文进行base64编码
print(b64encode(res).decode())
​
# 解密必须要创建新的对象 不然会报错 decrypt() cannot be called after encrypt()
# 因为同一个对象不允许这样操作 又加密 又解密
obj2 = DES.new("abcd1234".encode(), DES.MODE_CBC, iv="12345678".encode())
# print("解密:",obj2.decrypt(res).decode())
​
# 如果使用了填充 那么在解密的时候也需要去掉
print("解密:", unpad(obj2.decrypt(res), 8).decode())
3DES算法
  • 对数据进行3次DES加密

  • 有两种密钥模式:

    • 2-key: 长度16字节

    • 3-key(更安全): 长度24字节

  • 偏移量长度: 8字节

  • 模式(不同模式存在本质区别):

    • ECB: 需要密钥

    • CBC: 需要密钥(key)、偏移量(iv)

  • 比DES安全,但速度和安全性仍慢于AES

from Crypto.Cipher import DES3
from Crypto.Util.Padding import pad, unpad
from base64 import b64decode, b64encode
​
# 跟DES一样的 只不过对象名换了 然后要求的字节数不一样 16或者24
obj = DES3.new("abcd12341234567887654321".encode(), DES3.MODE_CBC, iv="12345678".encode())
res = obj.encrypt(pad("机密".encode(), 8))
print(b64encode(res).decode())
​
obj2 = DES3.new("abcd12341234567887654321".encode(), DES3.MODE_CBC, iv="12345678".encode())
print("解密:", unpad(obj2.decrypt(res), 8).decode())
AES算法
  • 使用最广泛的对称加密算法

  • 分组加密: 每次处理16字节的明文

  • 密钥长度:

    • AES-128: 128位密钥(16字节)

    • AES-192: 192位密钥(24字节)

    • AES-256: 256位密钥(32字节)

  • 偏移量长度: 16字节

  • 模式(不同模式存在本质区别):

    • ECB: 需要密钥

    • CBC: 需要密钥(key)、偏移量(iv)

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from base64 import b64decode, b64encode
​
# 跟DES一样的 只不过对象名换了 然后要求的字节数不一样 16或者24
obj = AES.new("abcd123412345678".encode(), AES.MODE_CBC, iv="12345678abcdefg1".encode())
# 因为不是16个字节 让值自动填充16个字节 和des基本一样
res = obj.encrypt(pad("机密".encode(), 16))
print(b64encode(res).decode())
​
obj2 = AES.new("abcd123412345678".encode(), AES.MODE_CBC, iv="12345678abcdefg1".encode())
print("解密:", unpad(obj2.decrypt(res), 16).decode())

3.4 RSA加密算法

RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。有两把对应密钥:公钥和私钥。用公钥加密只能用私钥解开,用私钥加密只能用公钥解密。

RSA加密解密网址: https://oktools.net/rsa

  • 公开密钥(publickey:公钥)

  • 私有密钥(privatekey:私钥)

  • 公钥和私钥是一对的

密钥长度: 128、256、384、512字节 特点:

  • 能够加密的明文长度有限,短于密钥长度

  • 计算量大,计算速度慢

  • 同样的密钥和明文,得到不一样的密文

3.4.1 RSA生成密钥
from Crypto.PublicKey import RSA
# 生成2048位 RSA 密钥对 2048指的是256个字符 单位是bit
key = RSA.generate(2048)
# 保存私钥
with open("private_key.pem", "wb") as f:
    f.write(key.export_key(format="PEM"))
# 保存公钥
with open("public_key.pem", "wb") as f:
    f.write(key.publickey().export_key(format="PEM"))
print("私钥已保存为 private_key.pem")
print("公钥已保存为 public_key.pem")
3.4.2 RSA加解密

RSA算法特点:

  • 使用最广泛的非对称加密算法

  • 公钥(Public Key): 公开用于加密

  • 私钥(Private Key): 保密用于解密

  • 密钥长度: 128、256、384、512字节

  • 能够加密的明文长度有限,短于密钥长度

  • 计算量大,计算速度慢

  • 同样的密钥和明文,得到不一样的密文

from Crypto.PublicKey import RSA
# 真正用来做RSA加密的一个对象
from Crypto.Cipher import PKCS1_OAEP
​
# 加载公钥的文件
with open('public_key.pem', 'r', encoding='utf-8') as f:
    # 读文件的内容
    public_key = RSA.import_key(f.read())
​
# public_key.size_in_bits() 这个方法可以看到它是2048位bit
# public_key.size_in_bytes() 这个方法可以看到它是256位字节
# 实例化对象
# obj = PKCS1_OAEP.new(public_key)
​
# 进行加密 hhh 是我们要加密的字符 然后转成二进制码再用16进制字符串输出
# 加密操作
encrypt_obj = PKCS1_OAEP.new(public_key)
plaintext = "hhh".encode()  # 加密明文
ciphertext = encrypt_obj.encrypt(plaintext)
print("加密后的密文(十六进制):", ciphertext.hex())
​
# 解密部分
# 加载私钥
with open('private_key.pem', 'r', encoding='utf-8') as f:
    private_key = RSA.import_key(f.read())
​
# 解密操作
decrypt_obj = PKCS1_OAEP.new(private_key)
decrypted_text = decrypt_obj.decrypt(ciphertext)  # 直接使用加密得到的字节
print("解密后的明文:", decrypted_text.decode())
​
# 如果从十六进制字符串解密(例如通过网络传输的密文):
ciphertext_from_hex = bytes.fromhex(ciphertext.hex())  # 转换回字节
decrypted_from_hex = decrypt_obj.decrypt(ciphertext_from_hex)
print("从十六进制解密结果:", decrypted_from_hex.decode())


网站公告

今日签到

点亮在社区的每一天
去签到