# pycryptodome模块 1. 安装 ```shell pip3 install pycryptodome ``` 2. 对称加密 + 流密码Salsa20 > 最自然的密码:它们一次加密一个字节的数据 + 块密码AES > 只能对固定数量的数据进行操作的密码。最重要的块密码是AES,其块大小为128位(16字节)。通常,块密码通常仅与操作模式一起使用,该操作模式允许加密可变数量的数据。某些模式(如 CTR)可以有效地将块密码转换为流密码。 3. 操作模式 + CBC > 创建一个新的 CBC 对象,使用<算法>作为基本块密码。 参数: 密钥(数据类型:字节) – 加密密钥 模式 – 常量Crypto.Cipher..MODE_CBC iv(数据类型:字节) – 初始化向量。对手无法预知的一段数据。它与块大小一样长(例如,AES为16字节)。如果不存在,则库将创建一个随机 IV 值。 4. 流密码Salsa20用法示例 ```python # 加密方法 from Crypto.Cipher import Salsa20 plaintext = b'Attack at dawn' secret = b'*Thirty-two byte (256 bits) key*' cipher = Salsa20.new(key=secret) msg = cipher.nonce + cipher.encrypt(plaintext) # 解密方法 from Crypto.Cipher import Salsa20 secret = b'*Thirty-two byte (256 bits) key*' msg_nonce = msg[:8] ciphertext = msg[8:] cipher = Salsa20.new(key=secret, nonce=msg_nonce) plaintext = cipher.decrypt(ciphertext) ``` 5. 块密码AES的CBC模式用法示例 ```python # 加密方法 import json from base64 import b64encode from Crypto.Cipher import AES from Crypto.Util.Padding import pad from Crypto.Random import get_random_bytes data = b"secret" key = get_random_bytes(16) cipher = AES.new(key, AES.MODE_CBC) ct_bytes = cipher.encrypt(pad(data, AES.block_size)) iv = b64encode(cipher.iv).decode('utf-8') ct = b64encode(ct_bytes).decode('utf-8') result = json.dumps({'iv':iv, 'ciphertext':ct}) print(result) '{"iv": "bWRHdzkzVDFJbWNBY0EwSmQ1UXFuQT09", "ciphertext": "VDdxQVo3TFFCbXIzcGpYa1lJbFFZQT09"}' # 解密方法 import json from base64 import b64decode from Crypto.Cipher import AES from Crypto.Util.Padding import unpad # We assume that the key was securely shared beforehand try: b64 = json.loads(json_input) iv = b64decode(b64['iv']) ct = b64decode(b64['ciphertext']) cipher = AES.new(key, AES.MODE_CBC, iv) pt = unpad(cipher.decrypt(ct), AES.block_size) print("The message was: ", pt) except (ValueError, KeyError): print("Incorrect decryption") ## 用于数据字节不够时自动填充数据 ```python # 导入模块 from Crypto.Util.Padding import pad,unpad # 自动填充 AES.new(key, AES.MODE_CBC).encrypt(pad(data, AES.block_size)) # 去除填充 AES.new(key, AES.MODE_CBC).encrypt(pad(data, AES.block_size)) ``` ## 加密数据填充示例 ```python from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad from Crypto.Random import get_random_bytes # 假设key是一个16字节的密钥 key = get_random_bytes(16) cipher = AES.new(key, AES.MODE_CBC) # 需要加密的数据 data = b"This is some data to encrypt" # 使用PKCS7进行填充 padded_data = pad(data, AES.block_size) # 加密填充后的数据 encrypted_data = cipher.encrypt(padded_data) # 你现在可以存储或发送 encrypted_data 和 cipher.iv (初始化向量) # ... # 解密时,你需要使用相同的初始化向量和密钥 decipher = AES.new(key, AES.MODE_CBC, iv=cipher.iv) decrypted_padded_data = decipher.decrypt(encrypted_data) # 移除填充 decrypted_data = unpad(decrypted_padded_data, AES.block_size) # decrypted_data 现在应该与原始数据相同 print(decrypted_data) ``` ## 生成随机秘钥 ```python # 导入模块 from Crypto.Random import get_random_bytes # 用法 get_random_bytes(16) ``` ## 数据转换内置库 ```python # 二进制数据与十六进制数据互相转换的库 from binascii import a2b_hex,b2a_hex # 将字符串转换为二进制 a2b_hex('abcdef1234') # 将二进制数据转换为base64编码的二进制数据 from base64 import b64encode,b64decode ```