Python 第三方模块之 PyCrypto - 加密解密

pycrypto:https://pypi.org/project/pycrypto/
pycryptodome:

1、简介

PyCrypto 是 Python 中密码学方面最有名的第三方软件包。提供了一系列加密算法实现,使得开发者可以轻松地在Python项目中加入加密和解密的功能。

可惜的是,它的开发工作于2012年就已停止。推荐使用它的后继者 PyCryptodome。PyCryptodome 是完全由 PyCrypto 的一个分支社区开发的,它保留了 PyCrypto 的接口,同时引入了新的特性和改进。以下是PyCrypto与PyCryptodome之间的一些主要比较:

  • 维护状态 :PyCrypto已经停止维护,而PyCryptodome目前仍然活跃并且持续更新。
  • 模块和接口 :PyCryptodome对PyCrypto的接口进行了扩展和增强,增加了新的加密算法和功能。
  • 兼容性 :PyCryptodome向后兼容PyCrypto,所以从PyCrypto迁移到PyCryptodome相对容易。

在替换 PyCrypto 时,你可以直接用 PyCryptodome 来替代 PyCrypto 模块,大多数代码可以直接运行而不需要改动。

其他 Python 加密库

除了 PyCryptodome 之外,还有许多其他的Python加密库可以作为PyCrypto的替代品。这些库各有特点,适用于不同的场景:

  • cryptography :一个非常活跃的项目,提供了强大的加密功能,包括加密套件、密钥生成和HMAC算法等。它还提供了Fernet加密工具,使得加密操作变得非常简单。
  • PyNaCl :这是NaCl( Networking and Cryptography library)的Python封装,提供一套高级的加密功能,包括对称加密、非对称加密、密钥对生成和消息认证码等。
  • hashlibhmac :这两个Python标准库提供了基础的散列函数和消息认证码功能。它们通常用于数据完整性检查和验证。

2、 安装

1
2
3
4
5
6
7
pip3 install -i https://pypi.douban.com/simple pycryptodome
# 导入
import Crypto

pip3 install -i https://pypi.douban.com/simple pycryptodomex
# 导入
import Cryptodome

3、DES(Data EncryptionStandard,即数据加密标准)

DES 是一种使用密钥加密的块算法,又被称为美国数据加密标准

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
from Crypto.Cipher import DES
from Crypto.Util.Padding import pad, unpad
from binascii import b2a_hex, a2b_hex


class DESUtil(object):
def __init__(self, key: bytes):
self.key = key # 密钥key 长度必须为 16 位 128 bit(AES-128)、24(AES-192)、或 32(AES-256)Bytes 长度
self.mode = DES.MODE_ECB
self.cryptor = DES.new(self.key, self.mode)

def encrypt(self, text: bytes) -> bytes:
# 加密函数,如果text不是16的倍数【加密文本text必须为16的倍数!】,那就补足为16的倍数
text = pad(text, DES.block_size)
# 把拼接后的 16 位字符后传入加密类中,结果为字节类型
encrypt_text = self.cryptor.encrypt(text)
# 因为AES加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题
# 所以这里统一把加密后的字符串转化为16进制字符串
return b2a_hex(encrypt_text)

def decrypt(self, text: bytes) -> bytes:
decrypt_text = self.cryptor.decrypt(a2b_hex(text))
return unpad(decrypt_text, DES.block_size)

4、3DES(或称为Triple DES)

3DES是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。它相当于是对每个数据块应用三次DES加密算法。

由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解。3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。

3DES(即Triple DES)是DES向AES过渡的加密算法(1999年,NIST将3-DES指定为过渡的加密标准),加密算法,其具体实现如下:设Ek()和Dk()代表DES算法的加密和解密过程,K代表DES算法使用的密钥,M代表明文,C代表密文,这样:

3DES加密过程为:C=Ek3(Dk2(Ek1(M)))

3DES解密过程为:M=Dk1(EK2(Dk3(C)))

5、AES(Advanced Encryption Standard, 高级加密标准)

AES 在密码学中又称 Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的 DES,已经被多方分析且广为全世界所使用。高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。

AES在软件及硬件上都能快速地加解密,相对来说较易于实作,且只需要很少的存储器。作为一个新的加密标准,目前正被部署应用到更广大的范围。

AES为分组密码,分组密码也就是把明文分成一组一组的,每组长度相等,每次加密一组数据,直到加密完整个明文。在AES标准规范中,分组长度只能是128位,也就是说,每个分组为16个字节(每个字节8位)。密钥的长度可以使用128位、192位或256位(16、24和32字节)。密钥的长度不同,推荐加密轮数也不同。

AES只是个基本算法,实现AES有若干模式。

  • AES.MODE_ECB:电子密码本模式,将每个明文块独立地加密成相应的密文块。ECB模式不提供加密的完全安全性,因为相同的明文块将始终加密成相同的密文块。
  • AES.MODE_CBC:在CBC模式中,每个明文块会与前一个密文块进行异或操作,然后再进行加密。需要一个初始向量(IV)来开始加密过程。
    • CBC 模式因为其安全性而被TLS(就是https的加密标准)和IPSec(win采用的)作为技术标准。
    • 简单地说,CBC 使用密码和 salt(起扰乱作用)按固定算法(md5)产生 key 和 iv。然后用 key 和 iv(初始向量,加密第一块明文)加密(明文)和解密(密文)。
  • AES.MODE_CCM:CCM模式是一种组合模式,它将CTR模式和CBC-MAC(密码分组链接消息认证码)组合在一起。它提供了加密、解密和消息完整性验证的功能。
  • AES.MODE_CFB:CFB模式将前一个密文块作为密钥流的一部分,然后与明文进行异或操作,产生密文。类似于CBC模式,需要一个初始向量(IV)。
  • AES.MODE_CTR:CTR模式中,明文与一个计数器进行异或操作,生成密文。计数器可以是递增的,也可以是随机的,只要在加密和解密过程中保持一致即可。
  • AES.MODE_EAX:EAX模式是一种组合模式,它将CTR模式和CMAC(密码分组链接消息认证码)组合在一起。它提供了加密、解密和消息完整性验证的功能。
  • AES.MODE_GCM:GCM模式是一种组合模式,它将CTR模式和GMAC(Galois消息认证码)组合在一起。它提供了加密、解密和消息完整性验证的功能。
  • AES.MODE_OCB:OCB模式是一种组合模式,它将CTR模式和CMAC组合在一起,并引入了一种效率更高的计算方式。它提供了加密、解密和消息完整性验证的功能。
  • AES.MODE_OFB:OFB模式将前一个密文块作为密钥流的一部分,然后与明文进行异或操作,产生密文。类似于CFB模式,不需要初始向量(IV)。
  • AES.MODE_OPENPGP):OpenPGP模式是一种扩展的加密模式,用于与OpenPGP协议兼容的系统。
  • AES.MODE_SIV:SIV模式是一种认证加密模式,它提供了加密、解密和消息完整性验证的功能,并允许使用相同的密钥对多个消息进行加密,而不会泄漏关于明文的信息。

参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad,unpad
from binascii import b2a_hex, a2b_hex


class AESUtil(object):
def __init__(self, key):
self.key = key # 密钥key,字节串(bytes)类型,长度必须为 16(AES-128)、24(AES-192)、或 32(AES-256)Bytes
self.mode = AES.MODE_ECB # 加密模式。它应该是AES.MODE_XXX常量之一,如AES.MODE_ECB、AES.MODE_CBC 等
self.cryptor = AES.new(self.key, self.mode)

def encrypt(self, text):
# 加密函数,如果text不是16的倍数【加密文本text必须为16的倍数!】,那就补足为16的倍数
text = pad(text.encode(), AES.block_size)
# 把拼接后的 16 位字符后传入加密类中,结果为字节类型
encrypt_text = self.cryptor.encrypt(text)
# 因为AES加密时候得到的字符串不一定是ascii字符集的,输出到终端或者保存时候可能存在问题
# 所以这里统一把加密后的字符串转化为16进制字符串
return b2a_hex(encrypt_text).decode("utf8")

def decrypt(self, text):
decrypt_text = self.cryptor.decrypt(a2b_hex(text))
return unpad(decrypt_text, AES.block_size).decode("utf8")


if __name__ == '__main__':
pc = AESUtil(b'keyskeyskeyskeys') # 初始化密钥
e = pc.encrypt("00000")
d = pc.decrypt(e)
print(e, d) # a9755fd70d8d6db65a6fac12d4797dde 00000

6、SHA256(哈希函数)

哈希函数用于生成消息摘要,常用于数据完整性检查和密码存储。以下是使用SHA256哈希的示例:

1
2
3
4
5
6
7
8
9
from Crypto.Hash import SHA256


def hash_sha256(data):
hash_object = SHA256.new(data=data.encode())
return hash_object.hexdigest()
message = "Hello, SHA256!"
hashed = hash_sha256(message)
print(f"SHA256哈希值: {hashed}")

7、HMAC(消息认证码)

HMAC (Hash-based Message Authentication Code) 用于验证消息的完整性和真实性。以下是HMAC的使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from Crypto.Hash import HMAC, SHA256


def create_hmac(key, message):
hmac = HMAC.new(key, msg=message.encode(), digestmod=SHA256)
return hmac.hexdigest()


def verify_hmac(key, message, received_mac):
hmac = HMAC.new(key, msg=message.encode(), digestmod=SHA256)
try:
hmac.hexverify(received_mac)
return True
except ValueError:
return False


# 创建HMAC
secret_key = b"my_secret_key"
message = "Hello, HMAC!"
mac = create_hmac(secret_key, message)
print(f"HMAC: {mac}")
# 验证HMAC
is_valid = verify_hmac(secret_key, message, mac)
print(f"HMAC验证结果: {is_valid}")

Reference


Python 第三方模块之 PyCrypto - 加密解密
https://flepeng.github.io/021-Python-33-Python-第三方模块-35-加解密-Python-第三方模块之-PyCrypto-加密解密/
作者
Lepeng
发布于
2016年8月3日
许可协议