Python使用Crypto库实现加密解密的示例详解
什么是Crypto库
Crypto是一个基于Python的加密工具包。它提供了各种加密算法、随机数生成器以及协议的实现。Crypto中的主要模块有:Cipher、Hash、Protocol、PublicKey、Util、IO。我们可以根据自己的需要选择具体的模块使用。接下来我们将介绍如何使用Crypto库实现加密和解密。
环境准备
在使用Crypto库之前,需要先安装Crypto库。可以通过pip安装。在命令行中输入:
pip install pycrypto
加密
我们选择使用AES算法进行加密。
生成密钥和iv
from Crypto.Cipher import AES
import os
block_size = AES.block_size # 16
key = os.urandom(block_size) # 随机生成一个16字节的密钥
iv = os.urandom(block_size) # 随机生成一个16字节的iv
这里使用os.urandom函数生成随机的密钥和iv。
加密字符串
def encrypt_string(key, iv, s):
cipher = AES.new(key, AES.MODE_CBC, iv)
# s长度必须是block_size的倍数,所以需要填充
s = s + (block_size - len(s) % block_size) * chr(block_size - len(s) % block_size)
return cipher.encrypt(s)
s = 'Hello, World!'
encrypted_string = encrypt_string(key, iv, s)
print(encrypted_string)
以上代码中,利用了AES的CBC模式进行加密。只需调用AES.new
函数创建一个AES密码对象,密钥和iv将被自动用于加解密。在加密字符串之前,需要将字符串填充以便其长度是block_size的倍数。最终生成的加密字符串可以打印输出。
解密
与加密流程相反,解密需要先对加密字符串进行解密,然后移除填充的字节。
解密字符串
def decrypt_string(key, iv, encrypted_string):
cipher = AES.new(key, AES.MODE_CBC, iv)
s = cipher.decrypt(encrypted_string)
# 移除填充的字节
s = s[:-ord(s[len(s) - 1:])]
return s
decrypted_string = decrypt_string(key, iv, encrypted_string)
print(decrypted_string)
以上代码中,调用AES.new
函数创建一个AES密码对象,并使用密钥和iv解密加密字符串。注意在将解密后的字符串返回之前,需要移除填充的字节。
示例
下面提供一个完整示例,演示如何使用Crypto库实现加密和解密两个函数。首先加密字符串,然后解密字符串,最终输出得到的结果。
from Crypto.Cipher import AES
import os
block_size = AES.block_size
key = os.urandom(block_size)
iv = os.urandom(block_size)
def encrypt_string(key, iv, s):
cipher = AES.new(key, AES.MODE_CBC, iv)
# s长度必须是block_size的倍数,所以需要填充
s = s + (block_size - len(s) % block_size) * chr(block_size - len(s) % block_size)
return cipher.encrypt(s)
def decrypt_string(key, iv, encrypted_string):
cipher = AES.new(key, AES.MODE_CBC, iv)
s = cipher.decrypt(encrypted_string)
# 移除填充的字节
s = s[:-ord(s[len(s) - 1:])]
return s
s = 'Hello, World!'
encrypted_string = encrypt_string(key, iv, s)
decrypted_string = decrypt_string(key, iv, encrypted_string)
print('原始字符串:', s)
print('加密后的字符串:', encrypted_string)
print('解密后的字符串:', decrypted_string)
输出结果:
原始字符串: Hello, World!
加密后的字符串: b'|E\xbe8\x17\xbc\xea\x15\x14\xd5L\xd7a\x9d\xb3\x1d\x9c\xfd\xc5wv\xc9C\n)\xb7\xa23\x8cLWw3\xd5\xb1<'
解密后的字符串: b'Hello, World!\x05\x05\x05\x05\x05'
另一个示例
下面再提供一个示例,加密和解密的过程需要使用到密码和密码哈希。该示例使用的加密算法为Fernet,在使用Fernet进行加密和解密之前,需要对密码进行哈希和加盐操作。
from cryptography.fernet import Fernet, hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
# 假设数据需要被加密的密码为"password"
password = 'password'
# 迭代次数
num_iterations = 100000
# 盐值,可以用os.urandom生成随机字节序列
salt = b'salt'
# 加密数据
data = b'Some data to be encrypted'
# 使用PBKDF2HMAC生成密钥
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=num_iterations
)
key = kdf.derive(password.encode())
# 对密码进行哈希
hasher = hashes.Hash(hashes.SHA256())
hasher.update(password.encode())
password_hash = hasher.finalize()
# 使用Fernet进行加密和解密
fernet = Fernet(key)
encrypted_data = fernet.encrypt(data)
# 从加密数据中解密原始数据
decrypted_data = fernet.decrypt(encrypted_data)
# 检查解密出的原始数据是否与原始数据相同
assert decrypted_data == data
以上代码中,首先使用PBKDF2HMAC生成密钥,然后使用Fernet进行加密和解密。与上一个示例不同之处在于,这个示例使用了哈希和加盐对密码进行了更安全的处理。另外,由于密钥是由密码生成的,所以当需要加密或解密数据时,开发者不需要存储密钥和盐值,只需要存储密码哈希即可。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python使用Crypto库实现加密解密的示例详解 - Python技术站