目录
一、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)