一、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. 特點
- ECB(ElectronicCodebook,電子密碼本)
- 優點:簡單、可並行計算、誤差不傳遞
- 缺點:不能隱藏明文模式(比如圖像加密輪廓仍在)、主動攻擊(改明文,後續內容不影響,只要誤差不傳遞該缺點就存在)
- 用途:需要並行加密的應用
- 要求:一個十六位的key(密鑰)
- 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)