爬虫中常用的加密逻辑(python实现)

目录

一、MD5

二、URLEncode 和 Base64

1、URLEncode

2、Base64

三、对称加密

1、AES 加密

2、DES加密

四、非对称加密

1.RSA


一、MD5

from hashlib import md5     
# MD5是一个大的hash算法. 不是加密. 不存在解密逻辑

# hash 算法是不可逆的

salt = b"suibianjiashenmesalt"

# 加密器
obj = md5(salt)

# 准备好明文
massage = 'DK_COOl'
obj.update(massage.encode('utf-8'))    # 需要将字符串编码成字节

# 获取密文
ct_x = obj.hexdigest()
print(ct_x)         # 02350223f1dfe2ed625329c51c9cd26f, salt -> 8878d4fd97a85c434cc8ffeb70b658b9

注意:创建加密器时,加入 salt,可以使密文不那么容易被撞库。

MD5可以完成文件的校验。

扩展:sha256

不论是sha1,sha256,md5都属于摘要算法,都是在计算 hash 值. 只是散列的程度不同而已。这种算法有一个特性,他们是散列,不是加密。而且,由于 hash 算法是不可逆的,所以不存在解密的逻辑。


二、URLEncode 和 Base64

1、URLEncode

我们在访问一个url的时候总能看到这样一种URL:

https://sp1.baidu.com/5bU_dTmfKgQFm2e88IuM_a/union.gif?
q=execjs%2E%5Fexceptions%2EProcessExitedWithNonZeroStatus%3A+%281%2C+%27%27%2C+%27%5Bstdin%5D%3A1%5Cn%28function%28program%2C+execJS%29+%7B+execJS%28program%29+%7D%29%28function%28%29+%7B+function%28t%29+%7B%5Cn&rsv_ct=2&rsv_cst=1

此时会发现,在浏览器上明明是能看到中文的.但是一旦复制出来.或者在抓包工具里看到的.都是这种%.那么这个%是什么鬼?也是加密么?
非也,其实我们在访问一个ur的时候.浏览器会自动的进行urlencode操作.会对我们请求的ur进行编码.这种编码规则被称为百分号编码,是专门为url(统一资源定位符)准备的一套编码规则.
其实里面的规则非常简单.就是把ur中的参数部分转化成字节。每字节的再转化成1个16进制的数字.前面补%。

看着很复杂在python里直接一步到位

from urllib.parse import urlencode, unquote

# url 的 编码
base_url = 'https://www.baidu.com/s?'

param_dic = {
    "wd": "我饿了"
}

# wd=%E6%88%91%E9%A5%BF%E4%BA%86
result = urlencode(param_dic)
print(result)
url = base_url + result
print(url)

# 解码
url_1 = 'https://www.baidu.com/s?wd=%E6%88%91%E9%A5%BF%E4%BA%86'
print(unquote(url_1))   # 查看url 中的特殊符号以及中文信息

2、Base64

Base64其实很容易理解。通常被加密后的内容是字节,而我们的密文是用来传输的(不传输谁加密啊)。但是,在http协议里想要传输字节是很麻烦的一个事儿.相对应的,如果传递的是字符串就好控制的多.此时base64就应运而生了.26个大写字母+26个小写字母+10个数字+2个特殊符号(+和/)小组成了一组类似64进制的计算逻辑.这就是base64了.

import base64

bs = "我要吃饭,我饿fadksljfkljaskl呵啊哒。吃了么呵啊哒了".encode('utf-8')

# 编码
# base64主要是处理字节的
print(bs)
# 把字节 按照 base64的规则.进行编码。编码成base64的字符串形式
#           b64的字节      #b64的字符串
s = base64.b64encode(bs).decode("utf-8")
print(s)


# 解码
s = '5oiR6KaB5ZCD6aWt77yM5oiR6aW/ZmFka3NsamZrbGphc2ts5ZG15ZWK5ZOS44CC5ZCD5LqG5LmI5ZG15ZWK5ZOS5LqG'
bs = base64.b64decode(s)

source_s = bs.decode('utf-8')
print(source_s) # 我要吃饭,我饿fadksljfkljaskl呵啊哒。吃了么呵啊哒了

三、对称加密

        所谓对称加密就是加密和解密用的是同一个秘钥.就好比我要给你邮寄一个箱子.上面怼上锁.提前我把钥匙给了你一把,我一把。那么我在邮寄之前就可以把箱子锁上然后快递到你那里.你用相同的钥匙就可以打开这个箱子。


条件: 加密和解密用的是同一个秘钥.那么两边就必须同时拥有钥匙才可以。


常见的对称加密:AES,DES,3DES.我们这里讨论AES和DES

1、AES 加密

import base64

from Crypto.Cipher import AES

s = '这是我要加密的明文'
"""
key -> 16, 24, 32
It must be 16, 24 or 32 bytes long (respectively for *AES-128*,
        *AES-192* or *AES-256*).
"""
key = b'dkdkcooldkdkcool'

aes = AES.new(key, mode=AES.MODE_CBC, IV=b'0102030405060708')

# ValueError: Data must be padded to 16 byte boundary in CBC mode
# 需要做填充
# 填充最好的方案(通用):缺少字节的个数 * chr(缺少字节的个数)
bs = s.encode('utf-8')

que = 16 - len(bs) % 16     # 缺少字节的个数
bs += (que * chr(que)).encode('utf-8')

# 加密
result = aes.encrypt(bs)    # 要求加密的内容必须是字节
# 可以选择编码成 base64
# jL5CgtiUFlRJ1Oi/IGXutF9WLfAeRynlUOexzETGRT8=
b64 = base64.b64encode(result).decode()
print(b64)

# 如果aes对象 经过了加密。 就不能再解密了,必须重新写
miwen = "jL5CgtiUFlRJ1Oi/IGXutF9WLfAeRynlUOexzETGRT8="
aes1 = AES.new(key, mode=AES.MODE_CBC, IV=b'0102030405060708')

# 处理base64
miwen = base64.b64decode(miwen)
result = aes1.decrypt(miwen)
print(result.decode('utf-8').replace('', ""))

2、DES加密

跟 AES加密的实现方式 很像!

from Crypto.Cipher import DES

s = "我爱热巴"
key = b'dkdkcool'

des = DES.new(key, mode=DES.MODE_CBC, IV=b'01020304')

# 加密
bs = s.encode("utf-8")
que = 8 - len(bs) % 8  # 缺少字节的个数
bs += (que * chr(que)).encode('utf-8')
result = des.encrypt(bs)
print(result)

# 解密
miwen = b'\xc2[\xa5/u,\t \x95\xe0{Z\x8e\xc4?\xb7'
des1 = DES.new(key, mode=DES.MODE_CBC, IV=b'01020304')
result = des1.decrypt(miwen)
print(result.decode('utf-8').replace("", ""))

四、非对称加密

非对称加密:加密和解密的秘钥不是同一个秘钥。这里需要两把钥匙:一个公钥,一个私钥。公钥发送给客户端.发送端用公钥对数据进行加密.再发送给接收端,接收端使用私钥来对数据解密.由于私钥只存放在接受端这边。所以即使数据被截获了.也是无法进行解密的.
常见的非对称加密算法: RSA,DSA等等,我们就介绍一个.RSA加密,也是最常见的一种加密方案。

1.RSA

# ***************************************************************
# 1.生成私钥和公钥
import base64

from Crypto.PublicKey import RSA  # 管理秘钥的

rsa_key = RSA.generate(2048)

private_key = rsa_key.exportKey()
public_key = rsa_key.publickey().exportKey()

print(public_key)
with open("rsa_public_pem.txt", mode="wb") as f:
    f.write(public_key)
with open("rsa_private_pem.txt", mode="wb") as f:
     f.write(private_key)


# ***************************************************************
# 2. 加密

from Crypto.Cipher import PKCS1_v1_5  # 加密
from Crypto.PublicKey import RSA
import base64

# 2.1 准备明文
massage = '今天晚上没吃饭'

# 2.2 读取公钥
f = open('rsa_public_pem.txt', mode='r', encoding='utf-8')
# 2.3 把公钥字符串转化成 rsa_key (object)
rsa_key = RSA.import_key(f.read())
# 2.4 创建加密对象
rsa = PKCS1_v1_5.new(rsa_key)
# 2.5 加密
miwen = rsa.encrypt(massage.encode('utf-8'))
# 2.6 b64处理
miwen = base64.b64encode(miwen).decode('utf-8')
print(miwen)

# ***************************************************************
# 3. 解密
from Crypto.Cipher import PKCS1_v1_5
import base64
from Crypto.PublicKey import RSA

# 3.1 准备密文
ctx = 'UqkvnZf8Gd5F1dGxi/9+Nq7lBe1OKk1Kpbn0so0UIZivY3zFqH/UOEjau0/to4gOhtOZ0SNJ0CiKD3kIHqlNE07bY/eT15oqNj8qwMLZfGuUYcqnSDCqUi4qad1sZUlg9qrXHT2Ypr2VhZM2RT+6Fb4mUWb1M7RlTLfJUGkId1ixP7xZFeY7qf10eElrckW5dxX5EV6BZ2xRFxKizJV0DrgsPH44Ixn1cipokqFJGVBR2PnwY0Dwoy+Fcr/SjQe0tIxmRKVr2cU7eMjrsZFGBAYHEWujqfwNhWBgeoOmC9nJJS+GaIYKuCECXoQV1nRd9o/2JM2DvxzQi0zlVCYbBQ=='

# 3.2 读取私钥
f = open('rsa_private_pem.txt', mode='r', encoding='utf-8')
# 3.3 生成密钥对象
rsa_key = RSA.import_key(f.read())
# 3.4 生成解密对象
rsa = PKCS1_v1_5.new(rsa_key)
# 3.5 处理bs64,以及解密
mingwen_bytes = rsa.decrypt(base64.b64decode(ctx), None)
# 3.6 utf-8 处理
mingwen = mingwen_bytes.decode('utf-8')
print(mingwen)

猜你喜欢

转载自blog.csdn.net/m0_57126939/article/details/128137563
今日推荐