Files
docs/开发文档/python/pycryptodome.md
2026-01-14 11:27:47 +08:00

4.2 KiB
Raw Permalink Blame History

pycryptodome模块

  1. 安装

    pip3 install pycryptodome
    
  2. 对称加密

    • 流密码Salsa20

      最自然的密码:它们一次加密一个字节的数据

    • 块密码AES

      只能对固定数量的数据进行操作的密码。最重要的块密码是AES其块大小为128位16字节。通常块密码通常仅与操作模式一起使用该操作模式允许加密可变数量的数据。某些模式如 CTR可以有效地将块密码转换为流密码。

  3. 操作模式

    • CBC

      创建一个新的 CBC 对象,使用<算法>作为基本块密码。
      参数:
      密钥(数据类型:字节) 加密密钥
      模式 常量Crypto.Cipher..MODE_CBC
      iv数据类型:字节) 初始化向量。对手无法预知的一段数据。它与块大小一样长例如AES为16字节。如果不存在则库将创建一个随机 IV 值。

  4. 流密码Salsa20用法示例

    # 加密方法
    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模式用法示例

    # 加密方法
    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")
    
    
    

用于数据字节不够时自动填充数据

# 导入模块
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))

加密数据填充示例

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)

生成随机秘钥

# 导入模块
from Crypto.Random import get_random_bytes
# 用法
get_random_bytes(16)

数据转换内置库

# 二进制数据与十六进制数据互相转换的库
from binascii import a2b_hex,b2a_hex
# 将字符串转换为二进制
a2b_hex('abcdef1234')

# 将二进制数据转换为base64编码的二进制数据
from base64 import b64encode,b64decode