120 lines
4.2 KiB
Markdown
120 lines
4.2 KiB
Markdown
# 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
|
||
``` |