加密算法
爬虫开发中,我们经常遇到一些反扒措施就是数据加密,所以了解、掌握常见加密算的加密、解密法对于爬虫开发者来说是必须了解和掌握的。
一、 对称加密算法
1.定义
采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。由于其速度快,对称性加密通常在消息发送方需要加密大量数据时使用。但是,加解密双方使用同样的密钥进行加密和解密。密钥是控制加密及解密的指令,算法是一种规则,规定如何进行加密和解密。因此加密的安全性不仅取决于加密算法本身,密钥管理的安全性更是重要。因为加密解密都使用同一个密钥,如何把密钥安全地传递到解密者手上就成了必须要解决的问题。
2. 工作流程
下面简单举一个列子来说明一下对称加密算法的流程。甲和乙是生意上的合作伙伴,且两个公司分别在不同的城市,由于业生意上的需要,两公司相互之间经常邮寄很重要的货物,为了保障货物的安全,两公司商定制作一个保险柜,并打造两把相同的钥匙分别保管,以遍在收取包裹时用这把钥匙打开保险箱,以及在邮寄货物时将保险柜锁上。所以只要甲和乙保管好这把钥匙,就算保险柜丢失别人也无法打开。
3.常用算法
常用的对称加密算法有:DES、AES、3DES
DES
简介
DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。
DES 案例
from Cryptodome.Cipher import DES
import binascii
key = b'-88 key-' # 密钥 key 必须是 8个字节64位
# iv 参数也需要是一个8字节,64位的二进制数的初始化向量, 默认随机生成
# DES.MODE_OFB 加密模式
cipher = DES.new(key, DES.MODE_OFB, iv=b'12345678') # 创建一个加密对象
# 待加密数据
data = '我是一只小小鸟'.encode() # 转为二进制
# 加密
msg = cipher.encrypt(data)
# 输出二进制数据
print(msg)
# 输出16进制字符串
print(binascii.b2a_hex(msg))
# 解密过程
# 模式 key iv 和解密过程对应
cipher2 = DES.new(key, DES.MODE_OFB, iv=cipher.iv) # 创建一个新的解密对象
# 解密
res = cipher2.decrypt(msg)
print(res.decode('utf-8'))
加密结果:b'Q\x8f\xbb\xefi5\xfbq)\x9dO\xba@}\xce\x10\x14\xbd0\x9bg'
b'518fbbef6935fb71299d4fba407dce1014bd309b67'
解密: 我是一只小小鸟
3DES
简介
3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。它相当于是对每个数据块应用三次DES加密算法。由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解;3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。
3DES 案例
from Cryptodome.Cipher import DES3
# DES3 的加密解密过程
# 加密过程
# key 为24个字节长度,一般随机生成
# 本质上是三次des 的key 串联 k1, k2, k3
# 当k1=k2=k3 时,DES3 降级为 DES
key2 = b'12345678qwertyui12345678'
# 创建一个加密对象
cipher3 = DES3.new(key2, DES3.MODE_CFB)
# 加密
msg2 = cipher3.encrypt(data)
print(msg2)
# 解密
# 创建一个解密对象
cipher4 = DES3.new(key2, DES3.MODE_CFB, iv=cipher3.iv)
# 解密
res2 = cipher4.decrypt(msg2)
print(res2.decode('utf-8'))
加密结果: b'c\xaf}\xa1\nS\xc4\xc1I\x92l\xae\x16\x1a\x1e,\x91\xecF;\xd7'
解密结果:我是一只小小鸟
AES
简介
高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。
不同于它的前任标准DES,Rijndael使用的是代换-置换网络,而非Feistel架构。AES在软件及硬件上都能快速地加解密,相对来说较易于实作,且只需要很少的存储器。作为一个新的加密标准,目前正被部署应用到更广大的范围。
实际开发中使用AES加密需要注意的地方
-
服务端和我们客户端必须使用一样的密钥和初始化向量IV。
-
服务端和我们客户端必须使用一样的机密模式。
-
服务端和我们客户端必须使用一样的Padding模式。
以上三条有一个不满足,双方就无法完成互相加解密。
AES 案例
from Cryptodome.Cipher import AES
import binascii
# key 为16字节的密钥
key = b'1234567890123456'
data = '我是一只小小鸟'.encode()
cipher = AES.new(key, AES.MODE_EAX)
msg = cipher.encrypt(data)
print(binascii.b2a_hex(msg))
# 解密
cipher2 = AES.new(key, AES.MODE_EAX, nonce=cipher.nonce)
res = cipher2.decrypt(msg)
print(res.decode('utf-8'))
加密结果:b'4bc023fe72ab44fe3095faa2d6d4f204e37f4c85c2'
解密结果:我是一只小小鸟
二、非对称加密
定义
非对称加密算法是一种密钥的保密方法。
非对称加密算法需要两个密钥:公开密钥(publickey:简称公钥)和私有密钥(privatekey:简称私钥)。公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。
特点
非对称密码体制的特点:算法强度复杂、安全性依赖于算法与密钥但是由于其算法复杂,而使得加密解密速度没有对称加密解密的速度快。对称密码体制中只有一种密钥,并且是非公开的,如果要解密就得让对方知道密钥。所以保证其安全性就是保证密钥的安全,而非对称密钥体制有两种密钥,其中一个是公开的,这样就可以不需要像对称密码那样传输对方的密钥了。这样安全性就大了很多。
事实上,公钥加密算法很少用于数据加密,它通常只是用来做身份认证,因为它的密钥太长,加密速度太慢–公钥加密算法的速度甚至比对称加密算法的速度慢上3个数量级(1000倍)。
3.工作原理
- A要向B发送信息,A和B都要产生一对用于加密和解密的公钥和私钥
- A的私钥保密,A的公钥告诉B;B的私钥保密,B的公钥告诉A。
- A要给B发送信息时,A用B的公钥加密信息,因为A知道B的公钥。
- A将这个消息发给B(已经用B的公钥加密消息)。
- B收到这个消息后,B用自己的私钥解密A的消息。其他所有收到这个报文的人都无法解密,因为只有B才有B的私钥。
4.常用算法
非对称加密最常用,最广泛的算法是:RSA
RSA
简介
RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。今天只有短的RSA钥匙才可能被强力方式解破。到目前为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被解破的。
RSA 案例
import binascii
from Cryptodome.PublicKey import RSA
from Cryptodome.Cipher import PKCS1_OAEP
# 生成公钥 私钥
def generate_key():
key = RSA.generate(1024) # 生成密钥对
private_key = key.export_key() # 私钥
print(private_key)
# 将私钥写入文件中
with open('private_key.pem', 'wb') as f:
f.write(private_key)
public_key = key.publickey().export_key() # 公钥
print(public_key)
# 公私钥写入文件中
with open('public_key.pem', 'wb') as f:
f.write(public_key)
# 加密
def encrypt(data):
# 导入公钥
public_key = RSA.import_key(open('public_key.pem').read())
# print(public_key.e)
# print(public_key.n)
# 创建一个密码对象
cipher_rsa = PKCS1_OAEP.new(public_key)
msg = cipher_rsa.encrypt(data) # 加密
return msg
# 解密
def decrypt(msg):
# 导入私钥
private_key = RSA.import_key(open('private_key.pem').read())
cipher_rsa = PKCS1_OAEP.new(private_key)
res = cipher_rsa.decrypt(msg)
return res
if __name__ == '__main__':
msg = encrypt('我是一只小小鸟'.encode())
print(msg)
res = decrypt(msg)
print(res.decode('utf-8'))
以上是对一些常用的加密算的大概介绍,以及简单案例,如果有什么不对或错误的地方,希望各位大佬纠正。
下方代码是RSA在爬虫中的应用
# 有些网站会在请求过程中发送公钥,然后加密参数后传回后台来实现数据的加密
data = '我是一只小小鸟'.encode()
#网页上收到的 n 值
publkey_n = '8d7e6949d411ce14d7d233d7160f5b2cc753930caba4d5ad24f923a505253b9c39b09a059732250e56c594d735077cfcb0c3508e9f544f101bdf7e97fe1b0d97f273468264b8b24caaa2a90cd9708a417c51cf8ba35444d37c514a0490441a773ccb121034f29748763c6c4f76eb0303559c57071fd89234d140c8bb965f9725'
# e 常常为65537
publkey_e = 65537
# 生成公钥
private_key = RSA.RsaKey(n=int(publkey_n, 16), e=publkey_e)
# 创建 rsa 对象
cipher = PKCS1_OAEP.new(private_key)
msg = cipher.encrypt(data) # 解密
print(binascii.b2a_hex(msg)) # 输出16进制字符串