一、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(密钥)
  1. 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)