由來
做爬蟲逆向的時候, 經常要用到加密解密
目錄
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 + 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)
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()
審核編輯:劉清
-
字符串
+關注
關注
1文章
577瀏覽量
20486 -
加密算法
+關注
關注
0文章
211瀏覽量
25531 -
python
+關注
關注
56文章
4782瀏覽量
84468 -
加密解密
+關注
關注
0文章
9瀏覽量
2633
發布評論請先 登錄
相關推薦
評論