python加解密詳解

一、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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章