【爬虫】python复原网站前端密码加密
前言
前几天学完了尚硅谷的爬虫课程,这几天刚好有一门课出成绩了。我们学校的教务处的查分系统手机无法正常打开(好像只有ios设备用不了)。学校的一些学长弄了一个公众号,在公众号里面手机可以很方便的查到分数。这个公众号应该也是使用了爬虫技术查分,感觉非常方便。这次查完分数之后我就想着为什么不直接弄一个网络爬虫,然后搭建一个个人服务器,直接访问我自己的网站查分呢。想想就爽 !
发现问题-定位加密代码和加密的技术
之前在学习爬虫的时候没有见到过密码加密的情况,虽然知道一般前端的密码都会加密,但是当自己做爬虫遇到了还是有点不知所措的。
当我发现密码加密后,我就去网上搜了一通前端密码加密的方法。但是大都是理论,对于爬虫用处不大。后来我就去看了一下网站的源码,希望在网站源码中找到一些破解的方法。
我使用了Chrome浏览器,使用检查(快捷键:F12)功能,在source栏中查看网站的js文件,我找到了一个名字中有login的js文件,通过打断点调试,我找到了密码加密的函数。密码加密调用了另一个js文件中的函数,其代码如下(个人觉得找到前端加密代码很关键。下面的部分也都是以下面的网站前端JS加密代码为基础的):
function getCryptoPwd(pwd) {
var key = CryptoJS.enc.Utf8.parse(cryptoKey);
var password = CryptoJS.enc.Utf8.parse(pwd);
var encrypted = CryptoJS.AES.encrypt(password, key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.toString();
}
观察代码,发现问题的关键。好像使用了CryptoJS
网上搜一波。果然,这就是一个专门的前端加密的库。
现在的问题就是怎么样用Python
实现CryptoJS
的功能了。
寻找解决方法
通过搜索发现,python确实有一个功能和CryptoJS
类似的库Crypto
也支持多种加密方式。
解决方案-使用Python实现同样的加密
CryptoJS的AES加密简单来说就是应用 明文 和 密钥 在字节上的多次 位移 与 字节 间的 加 和 减 去加密数据的算法。AES加密有好几种模式,而这次网站中的加密模式是其中最简单的ECB模式(通过网站源码中的: mode: CryptoJS.mode.ECB)。
还需要注意的是encrypt函数中padding: CryptoJS.pad.Pkcs7参数。其为设置明文和密钥的填充方式。在加密前,需要将明文填充到16个字符长,Pkcs7填充模式就是在明文字符串末尾添加 (16 - 明文长度)的值直至明文到16位。
(这里真的不太讲的清,想了解还是再搜搜吧。。下面直接贴上代码吧)
import base64
from Crypto.Cipher import AES
# 获取密文的函数,参数位未加密的明文
def get_encrypted_password(password):
########## 秘钥 ##########
key = '' # 密钥因该可以在网站源码中找到,我要爬取的网站的密钥为16位,不需要再填充至16位了,这里就不展示具体的内容了
#########################
# 调用下面定义的 encrypt_password 函数,传递明文和密钥,返回密文
encrypted_password = encrypt_password(text=password,key=key)
return encrypted_password
# 输入明文和密钥,返回加密后的密文
def encrypt_password(text,key):
aes = AES.new(add_to_16(key), AES.MODE_ECB)
#先进行aes加密
encrypt_aes = aes.encrypt(add_to_16(text))
#用base64转成字符串形式
encrypted_text = str(base64.encodebytes(encrypt_aes), encoding='utf-8') # 执行加密并转码返回bytes
return encrypted_text
# 使用Pkcs7方案填充明文置16字节
def add_to_16(value):
addNum = 16-len(value) # 填充的值就是明文于填充的目标长度16的差值
addStr = chr(int(str(addNum),10)) # 使用chr 返回编码,具体为啥要这样我还数不清
while len(value) % 16 != 0:
value += addStr
return str.encode(value) # 返回bytes
总结
这次爬虫密码加密感觉还是比较成功的,虽然一些东西还没搞明白。但是总结下来这个工程让我对Python爬虫逆向工程复原前端加密过程的方法有了一些自己的方法论。
- 通过浏览器查看网页js源码,定位加密密码的前端代码,找到对应的加密算法
- 查找python是否有相关的库实现类似的加密算法
- 通过第三方库进行加密,必要时自己编程实现部分或全部功能
这次逆向工程用python加密密码下来感觉自己的pyhton基础还是不太行,而且有必要补一下。
emm如果有时间的话…