python爬虫之js逆向入门:常用加密算法的逆向和实践

news2024/12/21 22:41:38

一、强大的Chrome DevTools

Chrome DevTools是一组内置于Google Chrome浏览器中的开发者工具,用于帮助开发人员调试、分析和优化Web应用程序。它提供了一系列功能强大的工具,用于检查和编辑HTML、CSS和JavaScript代码,监视网络请求、性能分析,以及模拟移动设备等。(就是查看页面的组成代码和静态文件,也能调试js。)

1、Chrome DevTools的常用功能

1、元素面板(可以查看、修改html):用于检查和编辑页面的HTML和CSS代码,可以实时修改和预览效果。
2、控制台(执行js代码、打印log):用于在浏览器中执行JavaScript代码,并查看输出结果、错误信息和警告。
3、源码面板(可以查看和调试所有构成页面的代码,主要是可以调试js)面板用于查看和调试页面的源代码。
3、网络面板(浏览器自带的抓包工具):用于监视页面的网络请求,包括请求和响应的详细信息、加载时间、资源大小等。
4、性能面板(Performance Panel):用于分析页面的性能瓶颈,包括CPU和内存使用情况、页面加载时间、JavaScript执行时间等。
5、应用面板(Application Panel):用于查看和编辑浏览器的存储、缓存和Cookie信息,以及模拟离线状态和移动设备。
6、安全面板(Security Panel):用于检查网站的安全性设置,包括HTTPS证书、混合内容警告等。

2、最常用的两个面板-Sources面板和Networks面板

1、Chrome DevTools中的Sources面板

是一个强大的调试工具,它可以让你检查和调试JavaScript代码。Sources面板中提供了一些工具,如断点、调试、网络请求等,以帮助开发人员更好地理解和调试JavaScript代码。功能包括:
代码编辑器:Sources面板包含一个内置的代码编辑器,可以查看和编辑JavaScript源文件。
调试功能:可以在代码中设置断点,以便在执行到特定行时暂停代码的执行。还可以使用调试工具来逐步执行代码,并检查变量的值和执行结果。
监视功能:可以监视变量的值,并在值更改时自动暂停代码执行。
网络请求:Sources面板可以捕获和查看浏览器发出的网络请求,以及它们的响应。
控制台:Sources面板集成了控制台,可以在其中运行和调试JavaScript代码,以及查看打印的日志消息。
在使用Sources面板时,可以通过按F1键打开设置面板,以选择和配置特定的功能和快捷键。此外,Sources面板还支持导入和导出断点、黑盒脚本、预处理脚本等功能,以方便开发人员进行代码调试和管理。

2、Chrome DevTools中的Networks面板

是一个强大的工具,用于监视和分析浏览器发出的网络请求和响应。它提供了详细的网络性能信息,帮助开发人员优化网页加载速度和网络请求的效率。
请求监视:Networks面板会显示浏览器发出的每个网络请求,包括URL、请求方法、状态码、请求头、响应头等信息。你可以点击每个请求来查看其详细信息。
请求过滤:可以根据不同的类型(例如XHR、图片、CSS等)过滤和显示请求,以便更好地分析和检查特定类型的请求。
性能分析:Networks面板提供了丰富的性能数据,如请求时间、传输时间、响应大小等,以帮助你分析和优化网页的加载性能。
请求详细信息:你可以查看每个请求的详细信息,包括请求和响应的头部、查询参数、Cookies等。还可以查看请求的响应内容和预览。
延迟模拟:Networks面板允许你模拟不同的网络条件,如慢速3G、2G等,以便测试网页在不同网络环境下的性能表现。
WebSocket和Server-Sent Events监视:Networks面板可以监视和显示通过WebSocket和Server-Sent Events协议建立的实时连接。
通过使用Networks面板,你可以深入了解网页的网络请求和响应情况,识别性能瓶颈,优化网页加载速度,并确保网络请求的效率。它是Web开发过程中非常有用的调试和优化工具。

二、HTTP协议

1、http请求报文格式

request.png
抓包
image.png

2、http回应报文格式

response.png
抓包
image.png

3、代码中http组包

GET /login HTTP/1.1
Host: renren.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive

三、处理数据常见算法

1、Base64

Base64是一种编码方式,用于将二进制数据转换为可打印的ASCII字符序列。一般用于二进制数据在网络传输或存储时进行编码,ASCII字符序列可以跨平台传输和存储。编码过程中,如果二进制数据不足3个字节的,将被’='填充。
新浪登录接口用户名使用Base64进行编码 https://weibo.com/login.php
乐居 https://my.leju.com/web/sso/loginView#wt_source=bzdh_login

// 浏览器中
var str = '我是一只爬虫';
var encode_result = window.btoa(unescape(encodeURIComponent(str))); // 编码
var decode_result = decodeURIComponent(escape(window.atob('5oiR5piv5LiA5Y+q54is6Jmr')));

/*node 中 
修改源 npm config set registry https://registry.npm.taobao.org
查看修改结果 npm config get registry
*/

// 先安装 npm install base64 --save
// 编码字符串为base64
const base64 = require('base64');
let encodedString = base64.encode(str);
// 解码base64字符串
let decodedString = base64.decode(encodedString);

import base64
data = '我是一只爬虫'
# 编码
base64.b64encode(data.encode()) # b'5oiR5piv5LiA5Y+q54is6Jmr'
# 解码
base64.b64decode(b'5oiR5piv5LiA5Y+q54is6Jmr').decode()

"""
1、避坑 有的时候你会发现用在调试过程中明明是base64编码过的,
但是用python进行编码的时候,结果和浏览器中不一样,原因是十六进制的字符串数据,
转换成二进制时,使用的是bytes.fromhex()方法,而不是str.encode(),两者的结果截然不同的,
这种方法常用在对RSA、AES等加密结果进行编码的时候。
"""
data = 'a45737a515466fc33986f6e4717db9f3'
data.encode() # b'a45737a515466fc33986f6e4717db9f3'
bytes.fromhex(data) # b'\xa4W7\xa5\x15Fo\xc39\x86\xf6\xe4q}\xb9\xf3'

base64.b64encode(data.encode()) # b'YTQ1NzM3YTUxNTQ2NmZjMzM5ODZmNmU0NzE3ZGI5ZjM='
base64.b64encode(bytes.fromhex(data)) # b'pFc3pRVGb8M5hvbkcX258w=='

# 二进制转换成 js中类似charCodeAt()
data = b'\xa4W7\xa5\x15Fo\xc39\x86\xf6\xe4q}\xb9\xf3'
list(data) # 




2、哈希算法

哈希算法是一种将任意长度的输入数据转换为固定长度哈希值的算法。它通常用于对数据进行摘要、签名、验证等操作,具有以下特点:
不可逆性:哈希算法是单向的,即无法从哈希值还原出原始数据。无论输入数据有多长,生成的哈希值长度是固定的。
相同输入生成相同哈希值:对于相同的输入数据,无论何时何地进行哈希计算,都会得到相同的哈希值。这使得哈希算法非常适合用于数据的完整性验证。
雪崩效应:输入数据的微小改变会导致生成的哈希值发生巨大变化。即使原始数据只有一个字节的差异,哈希值也会完全不同。

1、MD5

MD5可以将任意长度的信息映射成16字节128位的二进制字符串(长度为32的十六进制字符串)。安全系数低,计算速度快。一般用在密码学、数字签名、数据完整性校验等领域。
(雪崩效应:MD5算法将输入的消息分成一系列512位的块,并对每个块进行一系列的操作,最终生成128位的哈希值。在每个块的处理过程中,MD5使用了四个非线性函数(F、G、H和I函数)以及一系列位操作(位移、异或等),这些操作使得输入数据的微小变化会导致输出哈希值的显著差异)
搜狐密码使用MD5 https://v4.passport.sohu.com/fe/login
人人网 签名 http://renren.com/login

// 引用CryptoJS
<script src="https://cdn.bootcdn.net/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>

// 加密
var hash = CryptoJS.MD5("hello world");

// 输出加密结果
console.log(hash.toString()); // 5eb63bbbe01eeed093cb22bb8f5acdc3

// 抖音X-Bogus参数过程中 会对Uint8Array进行MD5
uint8Array = new Uint8Array([1, 2, 3, 4]);
wordArray = CryptoJS.lib.WordArray.create(uint8Array);
CryptoJS.MD5(wordArray).toString(); // 08d6c05a21512a79a1dfeb9d2a8f262f

const CryptoJS  = require("crypto-js");
var res = CryptoJS.MD5(1);
console.log(res.toString())

/*
避坑指南 如果数据不是字符串,结果将是相同的 487f7b22f68312d2c1bbc93b1aea445b
Crypto.MD5(1).toString()
Crypto.MD5(2).toString()
Crypto.MD5([]).toString()
Crypto.MD5({}).toString()
CryptoJS.MD5(new Uint8Array()).toString()
Crypto.MD5([32, 0, 0, 0]).toString()

*/
https://github.com/brix/crypto-js/pull/296

import hashlib

message = b"hello world"

# 创建一个MD5对象
md5 = hashlib.md5()
# 更新MD5对象的内容
md5.update(message)  # 使用字节串进行更新
# 获取MD5的摘要值
digest = md5.hexdigest() # 5eb63bbbe01eeed093cb22bb8f5acdc3


# 另一种调用方式
md5 = hashlib.md5(message.encode()).hexdigest()


# 对Uint8Array进行MD5
hashlib.md5(bytes([1,2,3,4])).hexdigest() # 08d6c05a21512a79a1dfeb9d2a8f262f
# 利用numpy
import numpy as np
data = np.array([1,2,3,4], dtype=np.uint8)
hashlib.md5(data).hexdigest() # 08d6c05a21512a79a1dfeb9d2a8f262f

2、SHA1

SHA-1用于将任意长度的数据转换为固定长度的摘要值,通常为20字节160位的二进制字符串(长度为40的十六进制字符串),安全系数和计算速度适中。
春秋旅游网 签名 https://my.springtour.com/member/login

// 引用CryptoJS
<script src="https://cdn.bootcdn.net/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>


// 计算SHA-1哈希
var hash = CryptoJS.SHA1("hello world");
// 输出加密结果
console.log(hash.toString()); // 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed
import hashlib

# 计算SHA-1哈希
message = 'hello world'
sha1 = hashlib.sha1(message.encode()).hexdigest() 
print(sha1) # 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed

3、SHA256

SHA-256是一种安全哈希算法,用于将任意长度的数据转换为32字节256位的二进制摘要值(长度为64的十六进制字符串),安全系数高,计算速度慢。
中旅旅行 登录 (综合加密)https://www.ourtour.com/zl/login
易付宝 登录aes 签名sha256 https://paypassport.suning.com/ids/login

// 引用CryptoJS
<script src="https://cdn.bootcdn.net/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>


// 计算SHA-1哈希
var hash = CryptoJS.SHA256("hello world");
// 输出加密结果
hash.toString() // b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9



npm install jsrsasign
npm install node-rsa
npm install crypto-js


s = '2201f0c68a55-153a-43e7-b057-a031651c1e9d16858873806711.0'
var key = '-----BEGIN PRIVATE KEY-----MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC8gphg1cvDP45rAHzA1GmVc9+zTckvDQL4UK7zZHGHXmtClq0/KtPFw6jL9YoB7z6m1WPOE5JBm3dKgqK1KgEODXXf58cYexaE0dM0L/6XVPw57aomTgg8KFpRsKQb31b3gndP3OFXasu71NCVKLu+Rn9p4Qpa6syzWzfFsVR7KyJ1WY/vwVgviGfhVGAbtmKvOGEB6xR70joLVthxYPDP7cHpkabJU1CNWG/ZRzd06iW2odm+MrhHKl1VOhQVcqZF2D97El9waC0GEjnP/r2HVRZ/nmeKH2OeNPsQmyrYoGSKBJ8+QqwGpit6nFOSVDLFaNJg4OLkwiL9YFYvnhg5AgMBAAECggEAXpTfw2ZBsBsJZ+J8tXtd5mCXEq2qjXLn1JMW1IPG+naDNovHLPReANHktUDjF4lkU+ypANKNBWHtfnMBFAiZMuXKCKeQG1ZWvBlS8NJL2L4JNz9pqYJpW1Wby3TnQhzS06igGG/omCW7RujGJrCjUhqo/wSsX2WDg1H3L7eDfbAPqvipfvB/dtCy9SEbRJJCKuMpb50dOfUCRtRWtBEVa+HCRnJTl+W1gijzpgc9xme14oljExiviMO7pYt1+AC3DxGVXPqivOyc2qI0wDQqR2NOD0IQTRBRS2F5k8BjYM9o/gbjUIuxIcJOiDJFtzbi6lpV2YrNzFSwwYOtuXhYqQKBgQDtDvTkq34vKcyFNbwNe/7tXqh3AtGvXznR3mT7sePNtMNcJWjE1CgNJAbRcVoQkhr6t/bWU2lK+jLzAl4dfKpcg3G5VCuY2Fpm5oJC6JakzF8S0U65al4WOiC8B/lCW8/CFag8Z7xNm0bsTlsDZTBCbHMs1NLdhrV2uTaSEUFhzwKBgQDLkpSnmFRM8xwlZIOAX51+9a4yYRUHUfxiqi0Y7RT06l9+KgT13vxqUuykuFfAVtjZyn7vc5oOOr0dbMqm/MHhV9QnpfGhffpL6emgR7x4nnQ8XrJXIvky5EiGjnrFFfKsiIKuDKwhbslUHJmlrgP0kre0Tyb0etISSOSvKrmPdwKBgGSwAZxOqt3lZxT9ac5gaDryBaPm8qEGVUyqpUGyoQtyR7gPu5w+cHSEZND40ERRilwLXzBRZVuPQaytyMPFe6anvdn1wj69RkiGh7VbjQCaPZeEh2eBokzWi6jRyjFBRdEt2bMubHCaD1m3PjkG9aSA47qa+qVU3iZ7LI6F/btJAoGBAJh6cl4V+w6oCaz4XIcLFyzBWHjjvpx9DE3aqWzCJ7BK3LvjPVPscaQx+I5ohVHLuyFmSy2PqRR/aqdflWr+ZzoiTwZjhVkwwwmZayRilwjBps6RH4Ok7oLv+mLO1aZJijsxBLDZTRS9po8Z3Pv8G3pVasPjhYoZdL+9WYzas6KBAoGASBMQ1f2fu4agHVwYVI23xDJNPAktezX/K/xubJvU6umNpQhX8KMb2lb61+2tIYpgzVvG5rw3J9UVx4GmvuKO1l820u4gxd5mhwrQDS0r+DKTZDpzLvfoV4MRauS0n0asMHH/7unFStWCQ2jVvGVRUu2fcrFvEDcljFv9G29rBlc=-----END PRIVATE KEY-----'

var key = rs.KEYUTIL.getKey(key);

  // 创建 Signature 对象,设置签名编码算法
var signature = new rs.KJUR.crypto.Signature({ alg: "SHA256withRSA" });
// 初始化
signature.init(key);

signature.updateString(s);
// 生成密文
const originSign = signature.sign();
console.log(rs.hextob64(originSign))


import hashlib

# 计算SHA-256哈希
message = 'hello world'
sha256 = hashlib.sha256(message.encode()).hexdigest()
print(sha256) # b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9

3、加密算法

1、DES

DES是一种对称加密算法,它采用了分组密码的方式,将明文按固定长度的块进行加密。密钥长度为64位(8位字符串)
UU跑腿服务平台 http://open.uupt.com/#/

// 引用CryptoJS
<script src="https://cdn.bootcdn.net/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>

message = 'hello world'
key = '4706d6c8c3d8dd5a';
 // 只有8位

CryptoJS.enc.Hex.parse(key) // 将每2个16进制字符转换成1个2进制字符 对应python中的 bytes.fromhex(str) 
CryptoJS.enc.Utf8.parse(key) // 对数据进行UTF8编码 对应python中的 str.encode('utf-8')

// ECB 加密
ecb_encrypted = CryptoJS.DES.encrypt(message, CryptoJS.enc.Hex.parse(key), {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7
});
encryptedText = ecb_encrypted.toString() // tWXmK1ju9f2ObhV/U8IUXA==

// ECB 解密
decryptedBytes = CryptoJS.DES.decrypt({ ciphertext: cipherText }, CryptoJS.enc.Hex.parse(key), {
    mode: CryptoJS.mode.ECB,
  });
decryptedText = decryptedBytes.toString(CryptoJS.enc.Utf8); // 'hello world'

key = '4706d6c8';
iv = '5eb63bbb'; // 只有8位

// CBC模式加密
cbc_encrypted = CryptoJS.DES.encrypt(message, CryptoJS.enc.Utf8.parse(key), {
    iv: CryptoJS.enc.Utf8.parse(iv),
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7,
});
encryptedText = cbc_encrypted.toString(); // kjKZ7UXWaATiot8anmcsbQ==

// CBC解密
cipherText = CryptoJS.enc.Base64.parse(encryptedText);
decryptedBytes = CryptoJS.DES.decrypt(encryptedText, CryptoJS.enc.Utf8.parse(key), {
    iv: CryptoJS.enc.Utf8.parse(iv),
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7,
});
decryptedText = decryptedBytes.toString(CryptoJS.enc.Utf8); // 'hello world'




from Crypto.Cipher import DES3
from Crypto.Cipher import DES
from Crypto.Util.Padding import pad, unpad
import base64

message = 'hello world'
key = '4706d6c8c3d8dd5a'
"""
避坑指南
js 中key为4706d6c8也能加密,但是python中会报错,因为JS加密过程,key长度不够8位时会用0补齐长度
python 中将key赋值为 4706d6c800000000 即可,
因为bytes.fromhex会将将每两个十六进制字符转换为一个字节
"""

# ECB 加密
cipher = DES.new(bytes.fromhex(key), DES.MODE_ECB)
ciphertext = cipher.encrypt(pad(message.encode(), DES.block_size))
encrypted_text = base64.b64encode(ciphertext).decode() # tWXmK1ju9f2ObhV/U8IUXA==

# ECB 解密
cipher = DES.new(bytes.fromhex(key), DES.MODE_ECB)
decrypted_bytes = cipher.decrypt(base64.b64decode(encrypted_text))
decrypted_text = unpad(decrypted_bytes, DES.block_size).decode("utf-8")


# CBC 加密
key = '4706d6c8'
iv = '5eb63bbb' # 只有8位

cipher = DES.new(key.encode(), DES.MODE_CBC, iv.encode())
ciphertext = cipher.encrypt(pad(message.encode(), DES.block_size))
encrypted_text = base64.b64encode(ciphertext).decode() # jKlxcg9R8X1i/SJU4w1CJQ==

# CBC 解密
cipher = DES.new(key.encode(), DES.MODE_CBC, iv.encode())
decrypted_bytes = cipher.decrypt(base64.b64decode(encrypted_text))
decrypted_text = unpad(decrypted_bytes, DES.block_size).decode("utf-8")

2、3DES

3DES是DES算法的加强版。它使用了三次DES加密操作来增强数据的安全性,密钥长度为128位(16位字符串)
加密过程和DES类似。

3、AES

AES是一种对称加密算法,被广泛用于保护数据的机密性。它支持多种密钥长度,包括128位(16位字符串)、192位(24位字符串)和256位(32位),其中CBC模式需要一个初始向量(IV)作为第一个密文块的输入,长度必须为128位(16位字符串)。
锦江之星 登录密码 http://hotel.bestwehotel.com/NewLogin/
UU跑腿企业版 http://es.test.uupt.com/admin/#/login
超星云盘 https://passport2.chaoxing.com/login

// 引用CryptoJS
<script src="https://cdn.bootcdn.net/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>

message = 'hello world'
const key = '4706d6c8c3d8dd5af1dfcb661a0db335';
const iv = '5eb63bbbe01eeed093cb22bb8f5acdc3';

// ECB模式加密
ecb_encrypted = CryptoJS.AES.encrypt(message, CryptoJS.enc.Hex.parse(key), {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7
});
encryptedText = ecb_encrypted.toString()  // Zd5b5CjKKhR3rOE/2gBGYw==
// ECB解密
cipherText = CryptoJS.enc.Base64.parse(encryptedText);
decryptedBytes = CryptoJS.AES.decrypt({ ciphertext: cipherText }, CryptoJS.enc.Hex.parse(key), {
    mode: CryptoJS.mode.ECB,
  });
decryptedText = decryptedBytes.toString(CryptoJS.enc.Utf8); // 'hello world'

/*
避开坑指南
js CBC模式IV 超过16位时,加密过程中只截取前16位,通过processBlock方法可以看到处理过程。
*/
// CBC模式加密
cbc_encrypted = CryptoJS.AES.encrypt(message, CryptoJS.enc.Utf8.parse(key), {
    iv: CryptoJS.enc.Utf8.parse(iv),
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7,
});
encryptedText = cbc_encrypted.toString(); // kjKZ7UXWaATiot8anmcsbQ==
// CBC解密
cipherText = CryptoJS.enc.Base64.parse(encryptedText);
decryptedBytes = CryptoJS.AES.decrypt(encryptedText, CryptoJS.enc.Utf8.parse(key), {
    iv: CryptoJS.enc.Utf8.parse(iv),
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7,
});
decryptedText = decryptedBytes.toString(CryptoJS.enc.Utf8); // 'hello world'
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64
import binascii

key = '4706d6c8c3d8dd5af1dfcb661a0db335'
iv = '5eb63bbbe01eeed093cb22bb8f5acdc3'
message = 'hello world'
"""
必坑指南,加密的时候key由16进制到2机制有两种方法,并且加密结果不同
1. key.encode() # b'4706d6c8c3d8dd5af1dfcb661a0db335'
2. bytes.fromhex(key) # b'G\x06\xd6\xc8\xc3\xd8\xddZ\xf1\xdf\xcbf\x1a\r\xb35'
3. binascii.unhexlify(key) # b'G\x06\xd6\xc8\xc3\xd8\xddZ\xf1\xdf\xcbf\x1a\r\xb35'
其中2 3 对应 js中的 CryptoJS.enc.Hex.parse(key)
"""
# ECB 加密
cipher = AES.new(bytes.fromhex(key), AES.MODE_ECB)
encrypted_bytes = cipher.encrypt(pad(message.encode(), AES.block_size))
encrypted_text = base64.b64encode(encrypted_bytes).decode() # Zd5b5CjKKhR3rOE/2gBGYw== 

# ECB 解密
cipher = AES.new(bytes.fromhex(key), AES.MODE_ECB)
decrypted_bytes = cipher.decrypt(base64.b64decode(encrypted_text))
decrypted_text = unpad(decrypted_bytes, AES.block_size).decode("utf-8")

"""
python CBC 模式如果IV 超过16位加密会报错,所以必须是16位长度
"""
# CBC 加密
cipher = AES.new(bytes.fromhex(key), AES.MODE_CBC, bytes.fromhex(iv))
encrypted_bytes = cipher.encrypt(pad(message.encode("utf-8"), AES.block_size))
encrypted_text = base64.b64encode(encrypted_bytes).decode()

# CBC 解密
cipher = AES.new(bytes.fromhex(key), AES.MODE_CBC, bytes.fromhex(iv))
decrypted_bytes = cipher.decrypt(base64.b64decode(encrypted_text))
decrypted_text = unpad(decrypted_bytes, AES.block_size).decode("utf-8")


4、RSA

RSA是一种非对称加密算法,常用于数据加密和数字签名,会生成一对密钥,公开的是公钥,私钥的是私钥。
1、数字签名,用于确保数据的完整性和认证发送方的身份,一般使用私钥加密,公钥解密。
2、数据加密,一般使用公钥加密,私钥加密。
链家(贝壳) 登录密码 https://xa.lianjia.com/
新浪密码 https://www.sina.com.cn/
房天下 https://passport.fang.com/
东方财富 https://passport2.eastmoney.com/pub/login

var encryptor = new JSEncrypt();


// 生成密钥对
var encryptor = new JSEncrypt({ default_key_size: 2048 });
var keyPair = encryptor.getKey();
// 获取公钥和私钥
var publicKey = keyPair.getPublicKey();
var privateKey = keyPair.getPrivateKey();
console.log(publicKey);
console.log(privateKey);

// 设置公钥
var publicKey = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgtcLM2er6q7JlT/GFs55\nVAsf2ONVMFFQKTYWHgmpxp+UI0fqhRr6oLsuepy6ilcIfaHpjobX3MLLCrW4fSRG\nLiBW+ZiU8JLm8W7hQ3n36hyywRrTLbgelWvcg5z9wx2epneAQQSddoyBp9A9JaAc\nyPdIQbqb48n2T2QmZ+qZY7vvvIJ2lB0gdljmYTKB6y+eXZtzXOJ2drwh2QjmIxeL\nwH+LxQxQhkduE9nqKicc8c72GpgG1I96GHIXH2NfH3mBRSkVjX4UG9zdiNhgqxZo\nqHnPhYuj6IhB9LTTVwNItagg9gcT2d0NmuDLHg1xSuyNY6ZG88ryNj1DzVWvPhzw\nhwIDAQAB\n-----END PUBLIC KEY-----'

// 设置私钥
var privateKey = '-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEAgtcLM2er6q7JlT/GFs55VAsf2ONVMFFQKTYWHgmpxp+UI0fq\nhRr6oLsuepy6ilcIfaHpjobX3MLLCrW4fSRGLiBW+ZiU8JLm8W7hQ3n36hyywRrT\nLbgelWvcg5z9wx2epneAQQSddoyBp9A9JaAcyPdIQbqb48n2T2QmZ+qZY7vvvIJ2\nlB0gdljmYTKB6y+eXZtzXOJ2drwh2QjmIxeLwH+LxQxQhkduE9nqKicc8c72GpgG\n1I96GHIXH2NfH3mBRSkVjX4UG9zdiNhgqxZoqHnPhYuj6IhB9LTTVwNItagg9gcT\n2d0NmuDLHg1xSuyNY6ZG88ryNj1DzVWvPhzwhwIDAQABAoIBAAD8OI/fCHrgbREs\nJUQ3ss8wtEEwWQxfmGBvEVSRkw81VWq8mGX/MYLzVeLDel4fUKeNiBI0LrzxVJEU\nlDqRAtxHDxCbFwgGuyl3Qcf9y6GeLLRqjMuL1uMeKE9vZ7PH7dFoFfWnYL4rSbCn\nT0aQwZa70fX4v0LEWw/2+5kNubD4DxDzPvMMIPaextKzmWSBalNBsjt9So7ae4sW\n+tafKyu1BFa0ZLJ1X/LuLJBPadiiiw9PdN8IHBHgpPrdNk4O5Zm2OnfaNhqZfRmI\nofWt6+D+yB4lMxgJC2RXZVmNJmzS9TFHhOpVoR0hdYss08A2tw7giSi8ikmT/RD1\nXgbyr2kCgYEAtX72jyEo3a6zEdoxmz0Q9DAzCzJJKAG4WQaJF86qRadRX5Tnn3oK\nIWLCfIpJNU3NsWI/ItMHpRJYheRcF5sGmu+YfUh7T7hQDblQdVTynz3NdXvOXonR\nxcr3uMVUG1kig1cdwOuD6up0mZgu/FGZMlLc5tz/RxhY8r53ClkT+4kCgYEAuIzA\nm9HX+9eatOUyIgWgsqW+yI5x23r1kpN1uk4yw3B9xqihgBp3tM0KNA1VZORi81py\nNwLWXn9f7lczSO7yK0VQLV3RP/Ks3te11N5fJxfZruP3PwXvlaQDS1u8KHJes4tZ\nRYUFIDhLrnhy2yUtWK70aYto1doNe1z5oFJhN48CgYAetlderQvPR4rB0JxoWpMN\n30Ij+ORsQq5BUlvMjYo+syuP8xCm6e3g7Gdgz73HqVzPUYLBj9hRVKNqNNRoojEh\n8r1pJeTH/rZ9PAijcjaEP98OrF6lnMjEoa39tFahMhonA4zjYnc2P2pvu1LoG57C\n50a+QlNoYnRaz2QxehVpkQKBgDcBzQ8ktunb08MDZbP6VXGqMXl567ntpnCv/zEu\nybazOuoRrUGPogqD6vyk1MUjxdKfLNf0woycDq3t091zSz9Wg5ViF1KmNJyfUxVF\nyrrOQxX74OAqFsVVg53ck/LCVDPT3yH3ihWWcgho4mMra565VyR2ZyMGwWn5xnXg\n2BVFAoGAbuARCuT4AiWv9NksHvyvcWl7LvXMeNvc/GvT8VhGwtqXWTebVUNB5Z9a\nefCRktAlNhZNarvMl2sOo3FKYEb0fmoFMVddZaHfJ/5PVCRg6i/LoN9DZaQE4sGb\n1LRflR9v1vwMLj4gsznzd4Uyjiy5VBICPCk4xib7yMGk8ivatzw=\n-----END RSA PRIVATE KEY-----'

// 加载公钥
encryptor.setPublicKey(publicKey);

// 加载私钥
encryptor.setPrivateKey(privateKey);

// 待加密的数据
var text = 'hello world'

// 加密
var encrypted = encryptor.encrypt(text);
console.log(encrypted);

// 解密
var decrypted = encryptor.decrypt(encrypted);
console.log(decrypted);




<script src="https://cdnjs.cloudflare.com/ajax/libs/jsrsasign/8.0.20/jsrsasign-all-min.js"></script>
// 签名
signature = new KJUR.crypto.Signature({ alg: "SHA256withRSA" })
signature.init(privateKey);
signature.updateString(text);
sign = signature.sign()

// 验签
verified = new KJUR.crypto.Signature({ alg: "SHA256withRSA", prvkeypem: publicKey })
verified.updateString(text)
res = verified.verify(sign)

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
from Crypto.Hash import SHA256

# 生成密钥对
keys = RSA.generate(2048)
private_key = keys.export_key()
public_key = keys.publickey().export_key()

text = 'hello world'
public_key = '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgtcLM2er6q7JlT/GFs55\nVAsf2ONVMFFQKTYWHgmpxp+UI0fqhRr6oLsuepy6ilcIfaHpjobX3MLLCrW4fSRG\nLiBW+ZiU8JLm8W7hQ3n36hyywRrTLbgelWvcg5z9wx2epneAQQSddoyBp9A9JaAc\nyPdIQbqb48n2T2QmZ+qZY7vvvIJ2lB0gdljmYTKB6y+eXZtzXOJ2drwh2QjmIxeL\nwH+LxQxQhkduE9nqKicc8c72GpgG1I96GHIXH2NfH3mBRSkVjX4UG9zdiNhgqxZo\nqHnPhYuj6IhB9LTTVwNItagg9gcT2d0NmuDLHg1xSuyNY6ZG88ryNj1DzVWvPhzw\nhwIDAQAB\n-----END PUBLIC KEY-----'
private_key = '-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEAgtcLM2er6q7JlT/GFs55VAsf2ONVMFFQKTYWHgmpxp+UI0fq\nhRr6oLsuepy6ilcIfaHpjobX3MLLCrW4fSRGLiBW+ZiU8JLm8W7hQ3n36hyywRrT\nLbgelWvcg5z9wx2epneAQQSddoyBp9A9JaAcyPdIQbqb48n2T2QmZ+qZY7vvvIJ2\nlB0gdljmYTKB6y+eXZtzXOJ2drwh2QjmIxeLwH+LxQxQhkduE9nqKicc8c72GpgG\n1I96GHIXH2NfH3mBRSkVjX4UG9zdiNhgqxZoqHnPhYuj6IhB9LTTVwNItagg9gcT\n2d0NmuDLHg1xSuyNY6ZG88ryNj1DzVWvPhzwhwIDAQABAoIBAAD8OI/fCHrgbREs\nJUQ3ss8wtEEwWQxfmGBvEVSRkw81VWq8mGX/MYLzVeLDel4fUKeNiBI0LrzxVJEU\nlDqRAtxHDxCbFwgGuyl3Qcf9y6GeLLRqjMuL1uMeKE9vZ7PH7dFoFfWnYL4rSbCn\nT0aQwZa70fX4v0LEWw/2+5kNubD4DxDzPvMMIPaextKzmWSBalNBsjt9So7ae4sW\n+tafKyu1BFa0ZLJ1X/LuLJBPadiiiw9PdN8IHBHgpPrdNk4O5Zm2OnfaNhqZfRmI\nofWt6+D+yB4lMxgJC2RXZVmNJmzS9TFHhOpVoR0hdYss08A2tw7giSi8ikmT/RD1\nXgbyr2kCgYEAtX72jyEo3a6zEdoxmz0Q9DAzCzJJKAG4WQaJF86qRadRX5Tnn3oK\nIWLCfIpJNU3NsWI/ItMHpRJYheRcF5sGmu+YfUh7T7hQDblQdVTynz3NdXvOXonR\nxcr3uMVUG1kig1cdwOuD6up0mZgu/FGZMlLc5tz/RxhY8r53ClkT+4kCgYEAuIzA\nm9HX+9eatOUyIgWgsqW+yI5x23r1kpN1uk4yw3B9xqihgBp3tM0KNA1VZORi81py\nNwLWXn9f7lczSO7yK0VQLV3RP/Ks3te11N5fJxfZruP3PwXvlaQDS1u8KHJes4tZ\nRYUFIDhLrnhy2yUtWK70aYto1doNe1z5oFJhN48CgYAetlderQvPR4rB0JxoWpMN\n30Ij+ORsQq5BUlvMjYo+syuP8xCm6e3g7Gdgz73HqVzPUYLBj9hRVKNqNNRoojEh\n8r1pJeTH/rZ9PAijcjaEP98OrF6lnMjEoa39tFahMhonA4zjYnc2P2pvu1LoG57C\n50a+QlNoYnRaz2QxehVpkQKBgDcBzQ8ktunb08MDZbP6VXGqMXl567ntpnCv/zEu\nybazOuoRrUGPogqD6vyk1MUjxdKfLNf0woycDq3t091zSz9Wg5ViF1KmNJyfUxVF\nyrrOQxX74OAqFsVVg53ck/LCVDPT3yH3ihWWcgho4mMra565VyR2ZyMGwWn5xnXg\n2BVFAoGAbuARCuT4AiWv9NksHvyvcWl7LvXMeNvc/GvT8VhGwtqXWTebVUNB5Z9a\nefCRktAlNhZNarvMl2sOo3FKYEb0fmoFMVddZaHfJ/5PVCRg6i/LoN9DZaQE4sGb\n1LRflR9v1vwMLj4gsznzd4Uyjiy5VBICPCk4xib7yMGk8ivatzw=\n-----END RSA PRIVATE KEY-----'

# 加密
public_key = RSA.import_key(public_key.encode())
cipher = PKCS1_v1_5.new(public_key)
encrypted = cipher.encrypt(text.encode())
result = base64.b64encode(encrypted)

# 解密
private_key = RSA.import_key(private_key.encode())
cipher = PKCS1_v1_5.new(private_key)
decrypted = cipher.decrypt(encrypted, 'ValueError')
decrypted .decode()

# 签名 私钥签名 公钥验签

# 读取 RSA 私钥
private_key = RSA.importKey(private_key)
# 使用 PKCS1_v1_5 签名算法进行签名
hash_obj = SHA256.new(text.encode())
signer = PKCS1_v1_5.new(private_key)
signature = signer.sign(hash_obj)

print("签名结果为:", signature.hex())

4、算法的搜索特征

1、MD5输出长度固定为32位16进制的字符串
2、MD5算法源码中几个大数可作为关键字进行识别,1732584193、4023233417、2562383102、271733878
3、RSA 加密需要设置公钥,setPublicKey方法,加密调用方法一般为getKey().encrypt(),RSA每次加密结果不一样
4、一般签名使用hash算法进行计算的

5、python实现js中的函数

1、字符串转ASCII

1、字符串转换成ASCII码
text = 'hello world'

js 代码
function strtoascii(str){
  var asciiArr = [];
  
  for (let i = 0; i < str.length; i++) {
    var charCode = str.charCodeAt(i);
    asciiArr.push(charCode);
  }
  
  console.log(asciiArr);
  return asciiArr
}
strtoascii(text) // [72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33]

python 代码
def strtoascii(string):
    result = []
    for row in list(string):
        result.append(ord(row))
    return result
strtoascii(text) # [72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33]


2、json转换

data = {'name':'python', 'type':1}
jsondata = JSON.stringify(data) // 对应python json.dumps(data)
JSON.parse(jsondata)						// 对应python json.loads(jsondata)

3、Unicode和字符互转

// unicode 转字符
String.fromCharCode(65)  // A 对应python中的 chr(65)
// 字符转 Unicode
'ABC'.charCodeAt(0) // 65 对应python中的 ord('A')

4、常用函数

message = 'hello world'
// 索引
message.charAt(4) // o 
// 切片
message.substring(0,4) // hell 对应python message[0:4]

//周期执行, 每1秒执行一次函数,直到执行 clearInterval()
setInterval(function(){ console.log("Hello"); }, 1000);

// 延迟执行,延迟3秒后执行函数
setTimeout(function(){ console.log("Hello"); }, 3000 )

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1121279.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

redis怎么设计一个高性能hash表

问题 redis 怎么解决的hash冲突问题 &#xff1f;redis 对于扩容rehash有什么优秀的设计&#xff1f; hash 目标是解决hash冲突&#xff0c;那什么是hash冲突呢&#xff1f; 实际上&#xff0c;一个最简单的 Hash 表就是一个数组&#xff0c;数组里的每个元素是一个哈希桶&…

ida81输入密码验证算法分析以及破解思路

本文分析了ida81对输入密码的验证流程&#xff0c;分别对输入密码到生成解密密钥、密码素材的生成过程以及文件数据的加密过程这三个流程进行分析&#xff0c;并尝试找一些可利用的破绽。很遗憾&#xff0c;由于水平有限&#xff0c;目前也只是有个思路未能完全实现&#xff0c…

查看当前cmake版本支持哪些版本的Visual Studio

不同版本的的cmake对Visual Studio的版本支持不同&#xff0c;以下图示展示了如何查看当前安装的cmake支持哪些版本的Visual Studio。 1.打开cmake-gui 2.查看cmake支持哪些版本的Visual Studio

28. 使用 k8e 玩转 kube-vip with Cilium‘s Egress Gateway 特性

因为在私有云环境下,我们需要保障集群服务 APIServer地址的高可用,所以提供的方案就是使用一个 VIP 让 API Server 的流量可以负载均衡的流入集群。另外,kube-vip 还支持 Service LB,方便SVC 服务的负载均衡,结合 cilium Egress Gateway 特性可以做到集群内的容器对外访问…

canvas绘制刮涂层抽奖效果

实现的效果&#xff1a;主要用到画布设置图层覆盖效果globalCompositeOperation属性 实现的源代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"…

canvas常用的几种重叠绘图设置globalCompositeOperation

globalCompositeOperation描述了2个图形交叉的时候是什么样子&#xff0c;它的值有很多&#xff0c;这里就盗一张很经典的图&#xff1a; 我们来看一个source-in的例子吧&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset&q…

论文-分布式-并发控制-Lamport逻辑时钟

目录 前言 逻辑时钟讲解 算法类比为面包店内取号 Lamport算法的时间戳原理 Lamport算法的5个原则 举例说明 算法实现 参考文献 前言 在并发系统中&#xff0c;同步与互斥是实现资源共享的关键Lamport面包店算法作为一种经典的解决并发问题的算法&#xff0c;它的实现原…

VTM/VVC 编译与测试-- YUV与RGB空间转换

环境配置:ubuntu 18.04 一、VVC测试 软件下载: 官网下载 VVC:http://jvet.hhi.fraunhofer.de/ 这里可以选择版本。 编译工具: 在开始编译前,需要电脑的环境中中有gcc、g++、cmake、make这四个工具。 sudo apt-get install gcc g++ sudo apt-get install cmake sudo …

Android微信逆向--实现发朋友圈动态

Android微信逆向--实现发朋友圈动态 0x0 前言# 最近一直在研究Windows逆向的东西&#xff0c;想着快要把Android给遗忘了。所以就想利用工作之余来研究Android相关的技术&#xff0c;来保持对Android热情。调用微信代码来发送朋友圈动态一直是自己想实现的东西&#xff0c;研…

Internet Download Manager 逆向分析

写在前面 文章仅供学习&#xff0c;切勿用于商业用途&#xff0c;出于版权原因&#xff0c;文章不提供资源下载。 论坛上较早之前已经有前辈对IDM的序列号算法进行过逆向分析 以及最近有师傅尝试对本篇文章对象相同的版本进行了逆向分析&#xff0c;但是比较遗憾的是该文章并…

瑞萨e2studio(26)----SPI驱动TFT-LCD屏

瑞萨e2studio.26--SPI驱动TFT-LCD屏 概述视频教学csdn课程样品申请完整代码下载屏幕接口接线方式新建工程工程模板保存工程路径芯片配置工程模板选择时钟配置开始SPI配置SPI属性配置IO配置头文件定义回调函数lcd_init.clcd.c设置区域颜色显示字符串显示汉字显示图片结果演示 概…

点击查看详情 | 网页版微信客户管理系统如何操作试用?

微信作为我们日常生活中最常用的社交应用之一&#xff0c;早已成为我们与朋友、家人和同事保持联系的重要工具&#xff0c;也是营销引流的重要平台。 通过微信营销&#xff0c;可以比较精准定向亲近用户。而微信的功能并没有很能满足做微信营销的人群&#xff0c;所以我们需要借…

S5PV210裸机(五):定时器

本文主要探讨210定时器相关知识&#xff0c;210定时器主要包含PWN定时器&#xff0c;系统定时器&#xff0c;看门狗&#xff0c;RTC。 PWM定时器 210有5个PWM定时器,timer0、1、2、3通过对应PIO产生PWM波形信号并输出,timer4没有GPIO只产生内部定时器中断 PWM…

Python 安装CSF(布料模拟滤波)的环境配置

一、环境配置 1.1 下载源码: Github下载CSF库源码 1.2 解压文件如下: 二、安装CSF库 2.1在解压文件中找到python文件夹所在目录 2.2 输入cmd并回车,来打开终端窗口 2.3激活虚拟环境 通过: activate +你的虚拟环境名称。来激活安装CSF库的虚拟环境。【不执行此

k8s镜像加devops

展示 1.配套资料2.devops 3.elk日志收集 4.grafana监控 5.dashboard![在这里插入图片描述](https://img-blog.csdnimg.cn/bf294f9fd98e4c038858a6bf5c34dbdc.png 目的 学习k8s来来回回折腾很久了&#xff0c;光搭个环境就能折腾几天。这次工作需要终于静下心来好好学习了一…

【USMA】N1CTF2022-praymoon

前言 本题主要利用 USMA 解题&#xff0c;当然还有其他做法&#xff0c;暂时不表 程序分析 启动脚本就不看了&#xff0c;该开的保护都开了。看下文件系统初始化脚本&#xff1a; #!/bin/shmkdir /tmp mount -t proc none /proc mount -t sysfs none /sys mount -t devtmpf…

codeforces (C++ Haunted House)

题目&#xff1a; 翻译&#xff1a; 思路&#xff1a; 1、由题目可知&#xff0c;他想让我们判断交换相邻字符位置后将二进制转为十进制后&#xff0c;能否整除2的次方。能整除即输出需要交换的次数&#xff0c;不能则输出-1。&#xff08;例&#xff1a;输入3和010这组数据就…

二分查找:如何快速定位IP对应的省份地址?

文章来源于极客时间前google工程师−王争专栏。 通过IP地址查找IP归属地功能&#xff1a; 这个功能是通过维护一个很大的IP地址库来实现。地址库中包含IP地址范围和归属地的对应关系。 当我们查询202.201.133.13这个IP地址归属地时&#xff0c;在地址库中搜索&#xff0c;这个…

真实感受:是智能家居在选择合适的技术!

科技从来都是为了让我们的生活更加的简单、舒适&#xff0c;而智能家居的智能&#xff0c;体现在如何更更更方便的使用我需要控制的家居。 例如&#xff1a;下班躺在床上想休息&#xff0c;房间和大厅的灯还开着&#xff0c;这时你会选择什么产品躺着解决问题&#xff1f; 红外…

【MySQL】逻辑架构

逻辑架构 逻辑架构剖析服务器处理客户端请求连接层服务层SQL Interface : SQL接口Parser : 解析器Optimizer : 查询优化器Caches&Buffers : 查询缓存组件 引擎层存储层 SQL执行流程MySQL查询流程查询缓存解析器词法分析语法分析 优化器执行器 数据库缓冲池 逻辑架构剖析 服…