一、python加密方式
目前python支持的加密有一下几种方式:
md5
base64
AES
RSA
注意:python3里默认的str是unicode,所以需要encode
字符串,才可以进行加密
# 第一种方式
str = bytes('hello world', 'utf-8')
# 第二种方式
str = 'hello world'.endcode(encoding='utf-8')
# 如果没有encode,则会报错TypeError: Unicode-objects must be encoded before hashing
二、md5
加密
1. 摘要算法
是一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5是最常见的摘要算法,速度很快,生成结果是固定的128 bit字节,通常用一个32位的16进制字符串表示。
python的hashlib提供了常见的摘要算法,如MD5,SHA
2. 特点
- 该加密不可逆
- 速度快
- 较为安全
3. 用法
import hashlib
str = 'hello world'.encode(encoding='utf-8') # b'hello world'
md5 = hashlib.md5()
md5.update(str)
encode_str = md5.hexdigest() # 5eb63bbbe01eeed093cb22bb8f5acdc3
二、base64
加密解密
1. 概念
是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法
2. 特点
- 只能算是编码转换,不算严格的加密
- 编码后字符串的长度一定会被4整除
3. 用法
import base64
str = 'hello world'.encode(encoding='utf-8') # b'hello world'
state = base64.b64encode(str) # 加密 b'aGVsbG8gd29ybGQ='
decode = base64.b64decode(state) # 解密 b'hello world'
decode = decode.decode(encoding='utf-8') # hello world
三、AES
加密解密
1. 概念
AES加密方式有五种:ECB, CBC, CTR, CFB, OFB。出于安全性,推荐CBC加密。
2. 特点
1. ECB(ElectronicCodebook,电子密码本)
- 优点:简单、可并行计算、误差不传递
- 缺点:不能隐藏明文模式(比如图像加密轮廓仍在)、主动攻击(改明文,后续内容不影响,只要误差不传递该缺点就存在)
- 用途:需要并行加密的应用
- 要求:一个十六位的key(密钥)
2. CBC(Cipher Block Chaining,密码分组链接)
- 优点:不容易主动攻击(误差传递)、适合长报文,是SSL、IPSec标准
- 缺点:无法并行、误差传递
- 用途:长报文传输,SSL和IPSec
- 要求:一个十六位的key(密钥)和一个十六位iv(偏移量)
3. 用法
在 Windows下使用pycryptodome 模块pip install pycryptodome
在 Linux下使用pycrypto模块pip install pycrypto
import uuid
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
# 如果text不足16位的倍数就用空格补足为16位
def add_to_16(text):
if len(text.encode('utf-8')) % 16:
add = 16 - (len(text.encode('utf-8')) % 16)
else:
add = 0
text = text + ('\0' * add)
return text.encode('utf-8')
# 加密函数
def encrypt(text, key, iv):
mode = AES.MODE_CBC
text = add_to_16(text)
cryptos = AES.new(key.encode('utf-8'), mode, iv.encode('utf-8'))
cipher_text = cryptos.encrypt(text)
# 因为AES加密后的字符串不一定是ascii字符集的,输出保存可能存在问题,所以这里转为16进制字符串
return b2a_hex(cipher_text)
# 解密后,去掉补足的空格用strip() 去掉
def decrypt(text, key, iv):
mode = AES.MODE_CBC
cryptos = AES.new(key.encode('utf-8'), mode, iv.encode('utf-8'))
plain_text = cryptos.decrypt(a2b_hex(text))
return bytes.decode(plain_text).rstrip('\0')
if __name__ == '__main__':
res = str(uuid.uuid4())
res = res.replace('-', '')
key = res[:16]
res = str(uuid.uuid4())
res = res.replace('-', '')
iv = res[:16]
e = encrypt("hello world", key, iv) # 加密
d = decrypt(e, key, iv) # 解密
print("加密:", e)
print("解密:", d)