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

120 lines
4.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# pycryptodome模块
1. 安装
```shell
pip3 install pycryptodome
```
2. 对称加密
+ 流密码Salsa20
> 最自然的密码:它们一次加密一个字节的数据
+ 块密码AES
> 只能对固定数量的数据进行操作的密码。最重要的块密码是AES其块大小为128位16字节。通常块密码通常仅与操作模式一起使用该操作模式允许加密可变数量的数据。某些模式如 CTR可以有效地将块密码转换为流密码。
3. 操作模式
+ CBC
> 创建一个新的 CBC 对象,使用<算法>作为基本块密码。
参数:
密钥(数据类型:字节) 加密密钥
模式 常量Crypto.Cipher.<algorithm>.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
```