Python爬虫教程

第一章: 初学乍练-Python快速入门

第二章: 初窥门径-从全局把握网络爬虫

第三章: 爬虫数据-网页与JSON

第四章: 爬虫核心-HTTP协议

第五章: 手到擒来-数据的抓包

第六章: 利刃出鞘-HTTP请求库

第七章: 尘埃落定-数据的解析

第八章: 逆向初探-JS逆向

第九章: 爬虫进阶-Selenium, 中间人拦截

第十章:斗转星移-常用的反爬策略及应对方法

首页 > Python爬虫教程 > 第八章: 逆向初探-JS逆向 > 8.1节:前端常用加密算法

8.1节:前端常用加密算法

薯条老师 2021-03-15 08:16:12 239301 0

编辑 收藏

广州番禺Python爬虫小班周末班培训

第四期线下Python爬虫小班周末班已经开课了,授课详情请点击:http://chipscoco.com/?id=232

8.1.1 前端常用加密算法

站点在反爬策略中会对接口的请求参数进行加密,我们在编写爬虫程序时应当熟悉前端JS使用的常用加密算法,以破解接口的加密参数。前端常用的加密处理算法:Base64, MD5, SHA, HMAC, AES, RSA。

严格地说,Base64,MD5,SHA,HAMC并不是加密算法,初学者在学习时无需过于细究这些概念上的区别,熟练掌握其使用场景即可。

现在分别对这些算法进行讲解。

8.1.2 字节编码算法:Base64

Base64是一种数据编码方式,Base64中的64是指在这种编码规范中包含64个可打印字符。这64个字符,从0开始进行编号,最大的字符编号为63。所谓Base64编码,是指按照Base64中的编码规则将字节序列转换为Base64字符集中的字符。那么,具体是怎么编码的呢?

在Base64的编码规则中,以3个字节作为一组,1个字节有8位,那么3个字节就是24位,再将24位分成4组,每组就是6位,6位能覆盖到0到63的范围,刚好能与字符集里的字符对应起来。将24位分成4组,每组6位,又将每组的高位补两个0,这样3个字节就扩展为4个字节。更详细的编码细节,感兴趣的读者可参考官方文档。

使用Base64编码的作用在于减弱数据的可读性,增加破解难度。Python提供了内置模块base64,用来对字节进行base64编码。base64模块的常用方法:

方法

描述

b64encode(s)

s表示字节类型的对象,返回经过base64编码后的字节对象

b64decode(s)

  将经过base64编码后的s解码为编码前的对象

    urlsafe_b64encode(s)

s参数同b64encode, 该方法用来解决参数的URL编码问题

urlsafe_b64decode(s)

将经过base64编码后的s解码为编码前的对象

base64编码经常用于HTTP请求中,对请求参数进行编码。现在通过一则实例来掌握base64模块的用法。

import base64
 
 
password = "qwert"
# encode方法接收的参数类型必须为字节类型
# 所以需要执行字符串的encode方法,将其转换为字节类型
password_b64 = base64.b64encode(password.encode("utf-8")) 
 
"""
解码端通过b64decode来解码,参数同样为字节类型:
password = base64.b64decode(password_b64)
""

8.1.3 消息摘要算法:MD5

MD5是一种不可逆的散列生成算法,不论输入的长度为多少,输出的都为一个128位(16字节)的散列值。相同的输入得到的是相同的MD5值,利用MD5这样的特性,可校验数据的一致性。MD5很典型的一种应用场景是验证用户登录密码是否正确。

后端在用户认证过程中,先将客户端传递过来的用户密码生成一个MD5值,然后与数据库保存的MD5值进行比较,如果相等则用户密码输入正确。

在Python中可直接使用内置模块hashlib中的md5方法来生成散列值。haslib模块的md5方法:

方法

描述

md5(string=b'')

string参数用来传递字节类型的数据,返回一个md5的散列对象;

可执行md5散列对象的digest方法获取二进制散列,执行hexdigest方法获取十六进制散列。

实例代码

import hashlib
 

# 定义变量password表示用户密码
password ="simple"
 
# md5方法接收的数据类型为字节类型,需执行字符串对象的encode方法进行转换
md5_obj =hashlib.md5(password.encode())
# 获取密码的十六进制散列
password_hash = md5_obj.hexdigest()

8.1.4 安全散列算法:SHA

SHA的英文全称为Secure Hash Algorithm,是一个密码散列函数家族。SHA包含的散列算法主要有sha1,sha256等,其安全性高于MD5, 通常用来生成数字签名。

所谓的数字签名,是指由数据发送方才能生成,并且无法伪造的散列值。在Python中通过hashlib模块的sha函数簇来生成散列值,下表所示为常用的SHA算法:

方法

描述

sha1(string=b'')

string参数用来传递字节类型的数据,返回一个sha1散列对象;

可执行散列对象的digest方法获取二进制散列,执行hexdigest方法获取十六进制散列。

sha256(string=b'')

string参数用来传递字节类型的数据,返回一个sha256散列对象;

可执行散列对象的digest方法获取二进制散列,执行hexdigest方法获取十六进制散列。

代码实例可参考8.1.3节中的代码,用法都是一样的。

8.1.5 基于散列的消息认证码:HMAC

HMAC是基于散列函数和密钥来进行消息认证的一种机制。通过散列函数可以验证消息的完整性,而通过密钥来确认接收的消息是否为对方所发。在Python中可通过内置的hmac模块来生成基于散列的消息认证码。hmac模块的常用方法:

方法

描述

new(key, msg=None, digestmod='')

 该方法返回一个hmac对象,key表示字节类型的密钥,msg表示待生成摘要的消息。digestmod表示散列算法的名称,常用的参数有MD5,SHA1,SHA256。

hmac对象的常用方法:

方法

描述

update(msg)

 该方法表示用msg来更新hmac对象,msg表示待生成摘要的消息。重复调用时表示与上次的结果进行拼接。例如m.update(a),m.update(b)等价于m.update(a+b)

hexdigest()

 输出十六进制的消息摘要。digest方法是生成二进制的消息摘要。

实例代码

import hmac
 
# HMAC_KEY为生成消息摘要的密钥
HMAC_KEY = b'&^DRE45!@lpDF!25Tm2='
 
message = "春天,你好".encode("utf-8")
# 对message按SHA256算法生成摘要
sign =  hmac.new(HMAC_KEY,  message,  "SHA256").hexdigest()

8.1.6 对称加密与非对称加密

关于对称加密和非对称加密的介绍,可复习4.4节中的内容,不再赘述。AES是一种对称加密算法,加密和解密共用同一个密钥。AES常用的加密模式有ECB和CBC。密钥长度必须为16字节,24字节,或者32字节,且加密的数据长度必须是16的倍数。在Python中使用AES加密需安装pycryptodome模块:

pip install pycryptodome

Python中的AES加密实例:

from Crypto.Cipher import AES
import hashlib, base64
 
# 以md5的散列值作为密钥
AES_KEY = hashlib.("qwert".encode()).hexdigest().encode()
 
# 待加密明文的长度需为16的倍数
text=("1"*16).encode()
 
# 执行AES模块的new方法构造一个AES cipher对象
# 再执行AES cipher对象的encrypt方法对数据进行加密
en_text=base64.b64encode(AES.new(AES_KEY,AES.MODE_ECB).encrypt(text))
 
"""
之所以在AES加密以后再对密文进行base64编码,是为了消除某些特殊字符的影响
"""

RSA是一种非对称加密算法,在非对称加密算法中,有一个公钥和私钥的概念。公钥即公开的密钥,私钥即非公开的密钥。数据通过私钥加密,只能用公钥解密。反之亦然,数据用公钥加密,那么只能通过私钥解密。在Python中进行RSA加密需安装rsa模块:

pip install rsa
 
Python中的RSA加密实例:
import rsa
import hashlib
import json
  
# 执行rsa模块的newkeys方法来生成公钥和私钥
public_key, private_key = rsa.newkeys(1024)
 
# 构造字典对象cert,表示cert证书
cert = {  "Version": "v3", "Serial Number": 126822703,
"Signature Algorithm": "sha256", 
 
# (1) 通过PublicKey的save_pcks1方法将公钥转换为字节类型
# (2) 通过PublicKey的load_pcks1方法将字节类型转换为PublicKey对象
"Public  Key": public_key.save_pkcs1().decode("utf-8")
}
 
 
info = json.dumps(cert, ensure_ascii=False).encode("utf-8")
 
# 执行rsa模块的sign方法+RSA私钥+sha256散列算法生成一个加密签名
cert["Signature"] = rsa.sign(info, private_key, "SHA-256")
 
# 通过rsa模块的verify方法以及RSA公钥来对加密签名进行验证
# 如果验证失败会抛出异常
rsa.verify(info, cert["Signature"], rsa.PublicKey.load_pkcs1(cert["Public 
key"].encode("utf-8")))

非对称加密的安全性高于对称加密,在C/S通信模型中,非对称加密的私钥一般由服务端进行保管,而对称加密是通信双方都持有密钥。对称加密的优点是算法简单,加密速度快,一般用于一对一的数据加密传输。前端在进行加密处理时,通常不会单一地使用某一种加密算法,会组合多种算法或自定义加密算法对参数进行处理,同学们需重点理解每一种加密算法的特性和使用场景。

8.1.7 高薪就业班

(1) Python后端工程师高薪就业班,月薪10K-15K,免费领取课程大纲
(2) Python爬虫工程师高薪就业班,年薪十五万,免费领取课程大纲
(3) Java后端开发工程师高薪就业班,月薪10K-20K, 免费领取课程大纲
(4) Python大数据工程师就业班,月薪12K-25K,免费领取课程大纲

扫码免费领取学习资料:


欢迎 发表评论: