观鸟网 RSA加密 AES 解密

https://www.birdreport.cn/home/relay/page.html

加密入口

直接搜sign

解密入口

方法一:XHR断点,往上跟栈


方法二:hook

javascript 复制代码
(function () {
    var _parse = JSON.parse;
    JSON.parse = function (str) {
        console.log("Hook JSON.parse ------> ", str);
        debugger;
        return _parse(str);
    }
})();

代码

python 复制代码
import time
import uuid
import hashlib
import requests
import json
import base64
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
from Crypto.Cipher import AES
from Crypto.Util.Padding import unpad



def md5_encrypt(text):
    m = hashlib.md5()
    m.update(text.encode('utf-8'))
    return m.hexdigest()

def rsa_encrypt(text):
    # 1. 拼接标准 PEM 公钥格式(必须加头尾,否则无法解析)
    public_key = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCvxXa98E1uWXnBzXkS2yHUfnBM6n3PCwLdfIox03T91joBvjtoDqiQ5x3tTOfpHs3LtiqMMEafls6b0YWtgB1dse1W5m+FpeusVkCOkQxB4SZDH6tuerIknnmB/Hsq5wgEkIvO5Pff9biig6AyoAkdWpSek/1/B7zYIepYY0lxKQIDAQAB"
    pub_key = f"-----BEGIN PUBLIC KEY-----\n{public_key}\n-----END PUBLIC KEY-----"
    rsa_key = RSA.importKey(pub_key)
    cipher = PKCS1_v1_5.new(rsa_key)
    encrypted_bytes = cipher.encrypt(text.encode('utf-8'))
    encrypted_base64 = base64.b64encode(encrypted_bytes).decode('utf-8')

    return encrypted_base64


def aes_decrypt(encrypted_text):
    """
    使用 AES/CBC/Pkcs7 模式解密数据。
    """
    # 1. 直接定义字符串格式的 Key 和 IV
    key_str = 'C8EB5514AF5ADDB94B2207B08C66601C'
    iv_str = '55DD79C6F04E1A67'

    # 2. 将字符串转换为字节 (UTF-8 编码)
    key = key_str.encode('utf-8')
    iv = iv_str.encode('utf-8')

    # 3. 将 Base64 编码的密文解码为原始字节
    encrypted_bytes = base64.b64decode(encrypted_text)

    # 4. 创建 AES 解密器
    cipher = AES.new(key, AES.MODE_CBC, iv)

    # 5. 执行解密
    decrypted_padded = cipher.decrypt(encrypted_bytes)

    # 6. 去除填充并解码为字符串
    decrypted = unpad(decrypted_padded, AES.block_size)

    return decrypted.decode('utf-8')

# 机构活动
def signup():
    data = {
        "limit": "1500",
        "page": "1"
    }
    data = json.dumps(data, separators=(',', ':'))

    requestId = str(uuid.uuid4()).replace('-', '')
    timestamp = str(int(time.time() * 1000))
    sign = md5_encrypt(data + requestId + str(timestamp))
    print(sign)

    headers = {
        'Accept': 'application/json, text/javascript, */*; q=0.01',
        'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
        'Origin': 'https://www.birdreport.cn',
        'Pragma': 'no-cache',
        'Referer': 'https://www.birdreport.cn/',
        'Sec-Fetch-Dest': 'empty',
        'Sec-Fetch-Mode': 'cors',
        'Sec-Fetch-Site': 'same-site',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0',
        'requestId': requestId,
        'sec-ch-ua': '"Microsoft Edge";v="147", "Not.A/Brand";v="8", "Chromium";v="147"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Windows"',
        'sign': sign,
        'timestamp': timestamp,
    }

    data = rsa_encrypt(data)
    print(data)

    response = requests.post('https://api.birdreport.cn/front/unit/signup', headers=headers, data=data)
    print(response)

    json_data = response.json()
    if json_data['code'] == 0:
        encrypted_str = json_data['data']
        result = aes_decrypt(encrypted_str)
        print("解密结果:", result)

# 观鸟节
def activity():
    data = {
        "limit": "10",
        "page": "1"
    }
    data = json.dumps(data, separators=(',', ':'))

    requestId = str(uuid.uuid4()).replace('-', '')
    timestamp = str(int(time.time() * 1000))
    sign = md5_encrypt(data + requestId + str(timestamp))
    print(sign)

    headers = {
        'Accept': 'application/json, text/javascript, */*; q=0.01',
        'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6',
        'Cache-Control': 'no-cache',
        'Connection': 'keep-alive',
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
        'Origin': 'https://www.birdreport.cn',
        'Pragma': 'no-cache',
        'Referer': 'https://www.birdreport.cn/',
        'Sec-Fetch-Dest': 'empty',
        'Sec-Fetch-Mode': 'cors',
        'Sec-Fetch-Site': 'same-site',
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36 Edg/147.0.0.0',
        'requestId': requestId,
        'sec-ch-ua': '"Microsoft Edge";v="147", "Not.A/Brand";v="8", "Chromium";v="147"',
        'sec-ch-ua-mobile': '?0',
        'sec-ch-ua-platform': '"Windows"',
        'sign': sign,
        'timestamp': timestamp,
    }

    data = rsa_encrypt(data)
    print(data)

    response = requests.post('https://api.birdreport.cn/front/official/activity', headers=headers, data=data)
    print(response)
    print(response.text)
    json_data = response.json()
    if json_data['code'] == 0:
        encrypted_str = json_data['data']
        result = aes_decrypt(encrypted_str)
        print("解密结果:", result)




if __name__ == '__main__':
    signup()
    activity()
相关推荐
卷无止境12 分钟前
《Deep Analysis with Polars》进阶分析技巧——深入解读
后端·python
大博士.J15 分钟前
视频号主体违规与认证上限?正确的解决方式
运维·python·自动化
Mr.朱鹏27 分钟前
【FastAPI 全栈实战 | 第2篇】Pydantic 数据校验与响应模型 —— 让 Bug 死在请求进来的那一刻
人工智能·python·fastapi
Xiangchu_39 分钟前
安徽硅胶厂的转型困局:从家电到汽车,卡在哪
经验分享·python·阿里云·eclipse·汽车·制造
WindfallSheng43 分钟前
从Vibe Coding到Spec Coding:一套可落地的AI-SDD企业级研发实战工程
javascript·vue.js
Asize1 小时前
Agent 入门:从 LLM 与 Agent 的区别到 Function Calling
javascript·人工智能
CTA终结者1 小时前
近期AI量化工具推荐,围绕最难推进的环节选择
人工智能·python
谙忆1 小时前
Python 常用图像处理库速查:Pillow、OpenCV、rembg、pillow-simd 各擅长什么、怎么选
图像处理·python·pillow
敲代码的猴先生1 小时前
论文分享 | TensorAbuse:通过滥用TensorFlow API将AI模型转化为恶意软件
人工智能·python·语言模型·tensorflow·论文笔记
言乐61 小时前
Python视频相对亮度检测
数据库·python·计算机视觉·小程序·音视频