您的位置:首页 > 编程语言 > Python开发

Python爬虫进阶必备 | 关于AES 的案例分析与总结

2020-01-13 11:37 561 查看

目标网站

aHR0cHM6Ly93d3cuZG5zLmNvbS9sb2dpbi5odG1s

抓包与定位加密

先抓包看下请求【图1-1】

图1-1

可以看到这里 password、email 是加密的结果,_token 的值可以直接在页面里找到。

直接搜索

password:
就可以找到加密的地方了。【图1-2】

图1-2

打上断点就可以看到加密的逻辑了。【图1-3】

图1-3

看到这里就可以直接扣代码了,用 node.js 的 CryptoJS 可以直接实现。

这个比较简单,咸鱼直接上扣取后的运行结果。【图1-4】

图1-4

对于 AES 加密其实也是可以使用 Python 的加密库直接实现的,但是咸鱼自己测试了一下加密的结果,发现 AES 的 CBC加密结果和使用 Node.js 加密的结果不一致,也没有找到相关的说明文档,所以只能 po 一下 AES 的  ECB 加密的代码与 CBC 加密的代码作为示例,并不能保证这个加密代码的加密结果与 Node.js 的加密结果相同。

要运行下面的代码需要安装相应的 Python 包,网上的文章会推荐安装 PyCrypto 但是目前无法通过 pip 安装

PyCrypto
,建议替换为
PyCryptodome
pip3 install pycryptodome
# 豆瓣源安装:pip3 install -i https://pypi.douban.com/simple pycryptodome
相关的引入可以参考下面的代码:
from Crypto.PublicKey import RSA
from Crypto.Cipher import AES
from Crypto.Signature import PKCS1_v1_5
from Crypto.Hash import SHA256
以下示例代码源自网络,具体来源文章链接可见文末。

ECB 加密代码:

import base64
from Crypto.Cipher import AES

class UseAES:
"""
AES
除了MODE_SIV模式key长度为:32, 48, or 64,
其余key长度为16, 24 or 32
详细见AES内部文档
CBC模式传入iv参数
本例使用常用的ECB模式
"""
def __init__(self, key):
if len(key) > 32:
key = key[:32]
self.key = self.to_16(key)

@staticmethod
def to_16(key):
"""
转为16倍数的bytes数据
:param key:
:return:
"""
key = bytes(key, encoding="utf8")
while len(key) % 16 != 0:
key += b'\0'
return key  # 返回bytes

def aes(self):
return AES.new(self.key, AES.MODE_ECB)  # 初始化加密器

def encrypt(self, text):
aes = self.aes()
return str(base64.encodebytes(aes.encrypt(self.to_16(text))),
encoding='utf8').replace('\n', '')  # 加密

def decode_bytes(self, text):
aes = self.aes()
return str(aes.decrypt(base64.decodebytes(bytes(
text, encoding='utf8'))).rstrip(b'\0').decode("utf8"))  # 解密

if __name__ == '__main__':
aes_test = UseAES("xianyuxuepython")
a = aes_test.encrypt("咸鱼学Python")
print(a)
b = aes_test.decode_bytes(a)
print(b)
CBC模式:
#!/usr/bin/env python
# -*- coding=utf-8 -*-
import base64
from Crypto.Cipher import AES
import random

def pkcs7padding(text):
"""
明文使用PKCS7填充
最终调用AES加密方法时,传入的是一个byte数组,要求是16的整数倍,因此需要对明文进行处理
:param text: 待加密内容(明文)
:return:
"""
bs = AES.block_size  # 16
length = len(text)
bytes_length = len(bytes(text, encoding='utf-8'))
# tips:utf-8编码时,英文占1个byte,而中文占3个byte
padding_size = length if(bytes_length == length) else bytes_length
padding = bs - padding_size % bs
# tips:chr(padding)看与其它语言的约定,有的会使用'\0'
padding_text = chr(padding) * padding
return text + padding_text

def pkcs7unpadding(text):
"""
处理使用PKCS7填充过的数据
:param text: 解密后的字符串
:return:
"""
length = len(text)
unpadding = ord(text[length-1])
return text[0:length-unpadding]

def encrypt(key, content):
"""
AES加密
key,iv使用同一个
模式cbc
填充pkcs7
:param key: 密钥
:param content: 加密内容
:return:
"""
key_bytes = bytes(key, encoding='utf-8')
iv = key_bytes
cipher = AES.new(key_bytes, AES.MODE_CBC, iv)
# 处理明文
content_padding = pkcs7padding(content)
# 加密
encrypt_bytes = cipher.encrypt(bytes(content_padding, encoding='utf-8'))
# 重新编码
result = str(base64.b64encode(encrypt_bytes), encoding='utf-8')
return result

def decrypt(key, content):
"""
AES解密
key,iv使用同一个
模式cbc
去填充pkcs7
:param key:
:param content:
:return:
"""
key_bytes = bytes(key, encoding='utf-8')
iv = key_bytes
cipher = AES.new(key_bytes, AES.MODE_CBC, iv)
# base64解码
encrypt_bytes = base64.b64decode(content)
# 解密
decrypt_bytes = cipher.decrypt(encrypt_bytes)
# 重新编码
result = str(decrypt_bytes, encoding='utf-8')
# 去除填充内容
result = pkcs7unpadding(result)
return result

def get_key(n):
"""
获取密钥 n 密钥长度
:return:
"""
c_length = int(n)
source = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
length = len(source) - 1
result = ''
for i in range(c_length):
result += source[random.randint(0, length)]
return result

en_16 = 'abcdefgj10124567'
encrypt_en = encrypt(aes_key, en_16)
print(encrypt_en)
以上代码源自:

https://www.jianshu.com/p/5d27888e7c93

https://www.cnblogs.com/xuchunlin/p/11421795.html

https://www.zhangkunzhi.com/archives/163

总结

上面就是关于 AES 的总结示例,下次遇到类似的 AES 加密就可以直接使用上面举例的模板稍作修改就可以直接用了不用费劲的扣取代码了。类似加密网站如下:5Lit5Zu956e75Yqo5o6M5LiK6Zeo5oi355S15L+h5qyi5LmQR08=EOF

  • 点赞
  • 收藏
  • 分享
  • 文章举报
煌金 发布了131 篇原创文章 · 获赞 1 · 访问量 924 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: