由来
做爬虫逆向的时候, 经常要用到加密解密
目录
pkcs7填充: pad和unpad
crypto: 一个共同方法 + 一个例子
pkcs7填充: pad和unpad
1. 为什么要pkcs7填充?
因为pkcs7是当下各大加密算法都遵循的数据填充算法
2. 基础
1个字节有8位, 所以16个字节是128位, 比如: 一个字母a就是一个字节
16进制: 0-9, a,b,c,d,e,f, 其中a代表10,后面依次加1, 满16进一,所以 15对应\x0f,16对应\x10
转换:
int -> unicode: chr(1) 结果是 \x01
unicode -> int: ord('\x11')值为17
3. pkcs7补位规则
补位的个数: 不足16位字节的倍数,补足变成16位的倍数,如果刚好是16的倍数, 补16个字节
补位的值: 等于补位个数的unicode码, 比如:content有7位,那么补充9个字节,每个字节的值都是\x09
4. 如何获取真实字符串?
直接获取字符串的最后一个字符,转换为int即为补位的数, 然后,真实 = 原始字符串长度 - 补位的数
def pad(content: str, block_size: int = 16) -> str:
p_len = block_size - len(content) % block_size
p = p_len * chr(p_len)
return content + p
def unpad(content: str) -> str:
last_char = ord(content[-1])
# 获取真实字符串,去掉最后补位的数据
return content[:-last_char]
def test_pad():
# 计算字符数
assert 3 == len('11中'), 'pad china error'
assert 4 == len('abcd'), 'pad china error'
p1 = pad('1')
assert '1\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f' == p1, 'pad 1 error'
b = r'1\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f'
assert f'{b}' == repr(p1), 'pad 1 1 error'
p2 = pad('11')
assert '11\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e' == p2, 'pad 2 error'
p15 = pad('111111111122222')
assert '111111111122222\x01' == p15, 'pad 15 error'
p16 = pad('1111111111222222')
assert '1111111111222222\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' == p16, 'pad 16 error'
def test_unpad():
p1 = '1\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f'
assert '1' == unpad(p1)
p2 = '11\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e'
assert '11' == unpad(p2)
p15 = '111111111122222\x01'
assert '111111111122222' == unpad(p15)
p16 = '1111111111222222\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10'
assert '1111111111222222' == unpad(p16)
def pad(content: str, block_size: int = 16) -> str: p_len = block_size - len(content) % block_size p = p_len * chr(p_len) return content + pdef unpad(content: str) -> str: last_char = ord(content[-1]) # 获取真实字符串,去掉最后补位的数据 return content[:-last_char]def test_pad(): # 计算字符数 assert 3 == len('11中'), 'pad china error' assert 4 == len('abcd'), 'pad china error' p1 = pad('1') assert '1\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f' == p1, 'pad 1 error' b = r'1\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f' assert f'{b}' == repr(p1), 'pad 1 1 error' p2 = pad('11') assert '11\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e' == p2, 'pad 2 error' p15 = pad('111111111122222') assert '111111111122222\x01' == p15, 'pad 15 error' p16 = pad('1111111111222222') assert '1111111111222222\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' == p16, 'pad 16 error'def test_unpad(): p1 = '1\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f\x0f' assert '1' == unpad(p1) p2 = '11\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e' assert '11' == unpad(p2) p15 = '111111111122222\x01' assert '111111111122222' == unpad(p15) p16 = '1111111111222222\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10\x10' assert '1111111111222222' == unpad(p16)
crypto: 一个共同方法 + 一个例子
代码很简单, 不需要过多的解释
from base64 import b64decode, b64encode
from crypto.cipher import aes
from crypto.util.padding import pad, unpad
class cryptor():
def __init__(self, key: str, iv: str):
self.aes = aes.new(key.encode('utf8'), aes.mode_cbc, iv.encode('utf8'))
def encrypto(self, text: str) -> str:
p = pad(text.encode('utf8'), aes.block_size)
return b64encode(self.aes.encrypt(p)).decode('utf8')
def decrypto(self, text: str) -> str:
d = self.aes.decrypt(b64decode(text))
return unpad(d, aes.block_size).decode('utf8')
def call_en():
text = 'm3u8.okjx.cc|057f1eed099f2f7e'
key = 'dvyyrqlnprcmdqse'
iv = '057f1eed099f2f7e'
aes = cryptor(key, iv)
e1 = aes.encrypto(text)
assert e1 == 'nczvyrj2ipdksf2emvfzagvrtaj9d8exngpjptv1qtm=', 'encrypto error'
def call_de():
text = 'hcizzlcgjfm1lvajcebmhchheuysajgxpupl+l9bdw4jdd9ds5qcycvwn6spotdujy/tok+st2m//aeekndk6trz0gvfa1szui8j3xg2ttzxzmw/52wuxhr1vnxrbrz4socz2twsy1t63nijx3xacle6rxfsmbxupzstmq0pdssdnpt4h5hkyy1wo227zzcnxdauwo1wtvcdamiuxbs/9ikbqnfklzikvvdgjjjsvxrlwsd5t6v4i47cuagvtncxpf3cklm37lmewpzwskjkg/igkjrry9k2a/tdimwnu0jbsf0jlymnt/kt2os08jsrsgjpxonpeifipge6upgugq7+sabhvfdsfusdqdtwbhuyxjtzbixolyenggfr3ufwotp1pvwr4r7by2n7xj7gef6qmfjbu0yb1v4+2wx5ucy43954enigfbuw2zxi35y+oggkpunptzccvbgw871rjiu7invo+ixvqhgg+0fpjawuezwym4yaepohtxjyaqg+1xatcgfoktun21qqcdkauq=='
key = '0eae7a71512ec09c'
iv = '675480787382e6f4'
aes = cryptor(key, iv)
d1 = aes.decrypto(text)
vkey=5dd8a1f1c4657d16ee8f61cea9d4fedf5195b3f0404a4104e6877f4d61d6df3f02b8ea021782bff03319989d91af586088584d8db58c6908c6b83c02137ce54cb3f09873ac784efb2d24a2a4d041757d7e753a5523bb08ac010e33f4dd1f8a16f8266900ba457af5223db94a6187a6280cea7cca4bf76edc&qq=335583&from=www.nxflv.com'
assert d1 == d2, 'decrypto error'
def main():
call_en()
call_de()
if __name__ == '__main__':
main()
明纬电源40A导轨型冗余模块——DRDN40
混合式步进电机应用电子电路设计图
亚太股份获1.36亿元定点,预计2024年开始量产
西门子博途:通过“ 报告系统错误” 进行系统诊断
大多数人5G随身WiFi用户被商家引导,如何避免“劣质”随身WiFi?
关于python Crypto的知识整理
CAD教程之电缆装配的绘制(英文版)
合科泰集团祝大家中秋节幸福团圆、阖家欢乐!
一款磨刀机直流无刷电机软起动技术设计方案
相差400元的游戏手机,黑鲨2和黑鲨2 Pro该如何选?
三星会长李健熙:一己之力重塑韩企价值观
华为Mate10完全确定,华为Mate9却疯狂降至“新低价”!
【你问我答】 选数字地or模拟地?再弄错找我!
作为相互关联的链与币,为何结局却大相径庭?
SAW滤波器基本理论
区块链中心化集中式处理过程解析
2022最新综合布线规范标准来喽
用调压器测试微机消谐谐振的操作步骤
格力全新5G手机销量如何?
嵌入式:听说,嵌入式这个行业未来十年都不会卷?