Python中网易云评论区的encSecKey参数加密怎么正确处理?

小白尝试爬取网易云评论区内容在encSecKey参数处理上破防了求大神帮忙看一下,我看js基本上都靠gpt

params参数目前已搞定,由于js会在每次请求生成一个16位的随机数i作为params参数第二层加密的密钥,encSecKey是这个随机数i的RSA加密结果,目前可以做到现去网页手动扒i和encSecKey扔进post请求最后获得正确的json文件,但是一旦这个随机数自己生成并RSA加密返回的就是空内容状态码200,还有一个小点就是晚上拿中午取下来的i和encSecKey进行请求请求好像会被挂起
下面getRSAkey是我的key加密代码

    def getAEStext(self, a, b):
        iv = "0102030405060708"
        a = pad(a.encode('utf-8'), AES.block_size)
        cipher = AES.new(key=b.encode('utf-8'), mode=AES.MODE_CBC, IV=iv.encode('utf-8'))
        ciphertext = cipher.encrypt(a)
        print(base64.b64encode(ciphertext).decode('utf-8'))
        return base64.b64encode(ciphertext).decode('utf-8')
    def getRSAkey(self):
        e = int(self.e,16)#指数
        f = int(self.f,16)#模
        public_key = RSA.construct((f, e))
        #print(f'public_key{public_key}')
        cipher = PKCS1_OAEP.new(public_key)
        encrypted_message = cipher.encrypt(self.i.encode('utf-8'))
        #print('key')
        return encrypted_message.hex()

下面是网页的js,函数c是key的加密

    function c(a, b, c) {
        var d, e;
        return setMaxDigits(131),
        d = new RSAKeyPair(b,"",c),
        e = encryptedString(d, a)
    }
    function d(d, e, f, g) {
        var h = {}
          , i = a(16);//产生16位随机数
        return h.encText = b(d, g),//g和i是密钥
        h.encText = b(h.encText, i),//返回的是parmas
        h.encSecKey = c(i, e, f),
        h
    }
阅读 898
avatarAI BotBETA
在处理网易云评论区的 `encSecKey` 参数加密时,你遇到的问题可能涉及几个方面:随机数生成、RSA 加密实现以及可能的请求时间戳或防爬虫机制。以下是一些可能的解决方案和检查点:

1. **随机数生成**:
   - 确保你生成的随机数 `i` 是16位的,并且格式与网页JS中生成的相同(例如,都是十六进制字符串或字节序列)。
   - 你可以尝试直接使用JS代码在浏览器控制台生成随机数,然后将其复制到Python中,以验证随机数本身是否影响加密结果。

2. **RSA 加密实现**:
   - 你的 `getRSAkey` 方法中,`self.i` 应该是16位的随机数(字符串或字节),确保这一点。
   - 检查 `self.e` 和 `self.f` 是否正确地从JS代码中提取了RSA公钥的指数和模。
   - 验证 `PKCS1_OAEP` 填充方式是否与JS中的加密方式一致。
   - 你可以尝试将加密后的结果转换为十六进制字符串之前,先打印出来看看是否与JS加密的结果相似。

3. **请求参数和格式**:
   - 确保你发送的请求参数(包括 `params` 和 `encSecKey`)的格式与网页请求完全一致。
   - 检查是否有其他隐藏的请求参数或Headers,如 `Referer`、`User-Agent` 或 `Cookie`,这些可能影响服务器的响应。

4. **防爬虫机制**:
   - 网易云可能实施了防爬虫机制,如检查请求的时间戳、频率或来源。
   - 如果晚上使用中午的 `i` 和 `encSecKey` 会导致请求被挂起,这可能是因为这些值有时间限制或服务器记录了它们的生成时间。
   - 尝试在请求中添加合适的时间戳或随机字符串来绕过这种检查。

5. **调试和验证**:
   - 使用浏览器的开发者工具(如Chrome的DevTools)来观察和分析网页的真实请求。
   - 在Python中,你可以使用 `requests` 库来发送请求,并打印出请求和响应的详细信息来帮助调试。

如果以上步骤仍然无法解决问题,你可能需要更深入地分析JS代码,了解它是如何生成和加密这些参数的。此外,由于网易云可能随时更改其API和加密方式,因此保持对最新变化的关注也是非常重要的。
1 个回答

Python

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
import base64
import random
import string

def generate_random_string(length=16):
    return ''.join(random.choices(string.ascii_letters + string.digits, k=length))

def generate_iv():
    return ''.join(random.choices(string.ascii_letters + string.digits, k=16)).encode('utf-8')

def getAEStext(a, b):
    iv = generate_iv()
    a = pad(a.encode('utf-8'), AES.block_size)
    cipher = AES.new(key=b.encode('utf-8'), mode=AES.MODE_CBC, IV=iv)
    ciphertext = cipher.encrypt(a)
    return base64.b64encode(iv + ciphertext).decode('utf-8')

def getRSAkey(e_hex, f_hex, message):
    e = int(e_hex, 16)
    f = int(f_hex, 16)
    public_key = RSA.construct((f, e))
    cipher = PKCS1_OAEP.new(public_key)
    encrypted_message = cipher.encrypt(message.encode('utf-8'))
    return encrypted_message.hex()

# 示例使用
random_string = generate_random_string()
encrypted_key = getRSAkey('your_e_hex', 'your_f_hex', random_string)

print(f'Random String: {random_string}')
print(f'Encrypted Key: {encrypted_key}')

javascript

function c(a, b, c) {
    setMaxDigits(131);
    var d = new RSAKeyPair(b, "", c);
    var e = encryptedString(d, a);
    return e;
}

function d(d, e, f, g) {
    var h = {};
    var i = generateRandomString(16); // 产生16位随机数
    h.encText = b(d, g); // g和i是密钥
    h.encText = b(h.encText, i); // 返回的是parmas
    h.encSecKey = c(i, e, f);
    return h;
}

function generateRandomString(length) {
    var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    var result = '';
    for (var i = 0; i < length; i++) {
        result += chars.charAt(Math.floor(Math.random() * chars.length));
    }
    return result;
}

// 示例使用
var randomString = generateRandomString(16);
var encryptedKey = c(randomString, 'your_e', 'your_f');
console.log('Random String:', randomString);
console.log('Encrypted Key:', encryptedKey);
宣传栏