一、对称加密算法 AES
1.简介
密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES(Data Encryption Standard),已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院 (NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一 。
该算法为比利时密码学家Joan Daemen和Vincent Rijmen所设计,结合两位作者的名字,以Rijdael之名命之。
2.加密模式
AES(Advanced Encryption Standard)是一种对称加密算法,它通常使用128位、192位或256位密钥进行加密和解密。下面是一些常见的AES加密模式:
(1)ECB(Electronic Code Book):这是最简单的加密方式,其中数据块被分成固定长度的大小,然后对每个分组应用一个特定的加密函数。
(2)CBC(Cipher Block Chaining):这是一种更复杂但更为安全的方法,它使用一个随机初始向量来确保数据块顺序正确。在每次加密过程中,都会生成一个新的密钥和IV。
(3) OFB(Output Feedback):这是CBC的一个变体,它使用一个输出向量来更新明文,而不是每次加密都使用一个新的密钥。这使得加密过程更加安全,并且更难被预测。
(4)CTR(Counter-Mode):这是OFB的变体,其中数据块被分成固定长度的部分,在每个部分应用不同的加密函数。这种方式通常用于高速数据传输中,因为可以减少处理延迟。
(5)CFB(Counter-Feedback):这是一种CB和CFS模式组合起来的加密方式,它结合了CB的可预测性和OFB的安全性。
每种AES加密模式都有其特定的优势和适用场景。选择适合当前任务或需求的加密模式是至关重要的,这需要根据具体情况来决定。
3.Python 实现AES (CBC模式)加密算法
(1)安装 cryptography 库
pip install pika cryptography
(2)Python 服务端程序
1)对文件加密
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from Crypto.Util.Padding import pad, unpad
# 生成一个随机的密钥
def generate_key(key_size=16):
return get_random_bytes(key_size)
# AES 加密文件
def aes_encrypt_file(input_file_path, output_file_path, key):
with open(input_file_path, 'rb') as input_file:
data = input_file.read()
cipher = AES.new(key, AES.MODE_CBC)
iv = cipher.iv
cipher_text = cipher.encrypt(pad(data, AES.block_size))
with open(output_file_path, 'wb') as output_file:
output_file.write(iv + cipher_text)
# AES 解密文件
def aes_decrypt_file(input_file_path, output_file_path, key):
with open(input_file_path, 'rb') as input_file:
iv = input_file.read(AES.block_size)
cipher_text = input_file.read()
cipher = AES.new(key, AES.MODE_CBC, iv)
plain_text = unpad(cipher.decrypt(cipher_text), AES.block_size)
with open(output_file_path, 'wb') as output_file:
output_file.write(plain_text)
# 示例使用
key = generate_key()
input_file_path = 'example.txt'
encrypted_file_path = 'encrypted.bin'
decrypted_file_path = 'decrypted.txt'
# 写入示例数据到文件
with open(input_file_path, 'w') as file:
file.write("This is a secret message.")
# 加密文件
aes_encrypt_file(input_file_path, encrypted_file_path, key)
print(f"File {input_file_path} encrypted to {encrypted_file_path}.")
# 解密文件
aes_decrypt_file(encrypted_file_path, decrypted_file_path, key)
print(f"File {encrypted_file_path} decrypted to {decrypted_file_path}.")
2)对字符串加密
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Random import get_random_bytes
# 生成 RSA 密钥对
def generate_keys(key_size=2048):
key = RSA.generate(key_size)
private_key = key.export_key()
public_key = key.publickey().export_key()
return private_key, public_key
# RSA 加密
def rsa_encrypt(message, public_key):
recipient_key = RSA.import_key(public_key)
cipher_rsa = PKCS1_OAEP.new(recipient_key)
encrypted_message = cipher_rsa.encrypt(message)
return encrypted_message
# RSA 解密
def rsa_decrypt(encrypted_message, private_key):
private_key = RSA.import_key(private_key)
cipher_rsa = PKCS1_OAEP.new(private_key)
decrypted_message = cipher_rsa.decrypt(encrypted_message)
return decrypted_message
# 示例使用
private_key, public_key = generate_keys()
message = b'This is a secret message.'
print(f"Original Message: {message}")
encrypted_message = rsa_encrypt(message, public_key)
print(f"Encrypted Message: {encrypted_message}")
decrypted_message = rsa_decrypt(encrypted_message, private_key)
print(f"Decrypted Message: {decrypted_message}")
二、非对称加密算法 RSA
1.简介
RSA(Rivest–Shamir–Adleman)是一种非对称加密算法,用于安全的数据传输。它由Ron Rivest、Adi Shamir和Leonard Adleman于1977年开发,是目前最广泛使用的公钥加密和数字签名算法之一。
RSA 对数据长度有一定的限制,具体来说,常见的 RSA 密钥长度:
(1)RSA-2048:支持加密的最大数据块大小约为 245 字节。
(2)RSA-3072:支持加密的最大数据块大小约为 359 字节。
(3)RSA-4096:支持加密的最大数据块大小约为 487 字节。
2.加密方式
RSA 算法的加密方式主要包括两种:加密数据和数字签名。这两种方式分别用于不同的安全需求。根据不同的应用场景和需求,RSA 加密也有多种具体的实现方式和填充方案。以下是主要的几种 RSA 加密方式:
(1)加密数据
用于保护数据的机密性,通过公钥加密数据,只有持有相应私钥的人才能解密。
1)PKCS#1 v1.5
PKCS#1 v1.5 是 RSA 的一种经典填充方案,定义了加密和签名的填充格式。在实际使用中,它已被更安全的填充方案(如 OAEP)所取代。
2)OAEP (Optimal Asymmetric Encryption Padding)
OAEP 是一种基于随机填充的 RSA 加密方案,提供了更高的安全性。它结合了哈希函数和随机填充,在现代加密系统中被广泛使用。
(2)数字签名
用于验证消息的完整性和身份认证,通过私钥生成签名,公钥验证签名。
1) PKCS#1 v1.5
与加密数据类似,PKCS#1 v1.5 也定义了签名的填充格式,但在签名过程中可能受到一定的攻击风险。
2) PSS (Probabilistic Signature Scheme)
PSS 是一种更安全的 RSA 签名填充方案,结合了哈希函数和随机填充,提供了较强的抗攻击性。
3.Python 实现RSA (数据加密-OAEP)加密算法
(1)安装了 pycryptodome 库
pip install pycryptodome
(2)加密字符串
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP, PKCS1_v1_5
from Crypto.Random import get_random_bytes
from Crypto.Signature import pkcs1_15
from Crypto.Hash import SHA256
# 生成 RSA 密钥对
def generate_rsa_key_pair(key_size=2048):
key = RSA.generate(key_size)
private_key = key.export_key()
public_key = key.publickey().export_key()
return private_key, public_key
# 使用 OAEP 加密
def rsa_encrypt_oaep(message, public_key):
recipient_key = RSA.import_key(public_key)
cipher_rsa = PKCS1_OAEP.new(recipient_key)
encrypted_message = cipher_rsa.encrypt(message)
return encrypted_message
# 使用 OAEP 解密
def rsa_decrypt_oaep(encrypted_message, private_key):
private_key = RSA.import_key(private_key)
cipher_rsa = PKCS1_OAEP.new(private_key)
decrypted_message = cipher_rsa.decrypt(encrypted_message)
return decrypted_message
# 使用 PKCS#1 v1.5 签名
def rsa_sign_v15(message, private_key):
private_key = RSA.import_key(private_key)
h = SHA256.new(message)
signature = pkcs1_15.new(private_key).sign(h)
return signature
# 使用 PKCS#1 v1.5 验证签名
def rsa_verify_v15(message, signature, public_key):
public_key = RSA.import_key(public_key)
h = SHA256.new(message)
try:
pkcs1_15.new(public_key).verify(h, signature)
return True
except (ValueError, TypeError):
return False
# 示例使用
private_key, public_key = generate_rsa_key_pair()
message = b'This is a secret message.'
print(f"Original Message: {message}")
# OAEP 加密与解密
encrypted_message = rsa_encrypt_oaep(message, public_key)
print(f"Encrypted Message (OAEP): {encrypted_message}")
decrypted_message = rsa_decrypt_oaep(encrypted_message, private_key)
print(f"Decrypted Message (OAEP): {decrypted_message}")
# PKCS#1 v1.5 签名与验证
signature = rsa_sign_v15(message, private_key)
print(f"Signature (PKCS#1 v1.5): {signature}")
is_valid = rsa_verify_v15(message, signature, public_key)
print(f"Signature valid (PKCS#1 v1.5): {is_valid}")
三、 RSA 和 AES 混合加密
针对RSA 加密存在对加密数据长度有一定限制,一般加密的数据不是很大。为了解决这一痛点问题,目前有一种优化方案:RSA 和 AES 混合加密,可以实现对大文本数据进行加密。
1.简介
将RSA与AES混合在一起的组合是RSA-AES(Rivest–Shamir–Adleman with Advanced Encryption Standard)技术,它结合了两者的优点。
-
安全性:RSA提供了对称密钥和非对称密钥的安全性。AES则提供了一个强大的数据加密机制。将两者结合使用可以提高安全性,因为它允许接收者根据私钥解密信息,并且确保只有发送者知道自己的公钥。
-
处理能力:虽然RSA-AES技术提高了安全性,但它的效率可能不如单独的RSA或AES高。这是因为RSA-AES需要计算大量的乘法和模数来加密数据。相比之下,AES提供了更快的加密速度,特别是在对称密钥情况下。
-
应用方面:RSA-AES通常用于提高电子商务的安全性,例如通过使用安全套接层(SSL)协议来保护在线支付过程。这种组合技术还可以用于数字签名、数字证书和更广泛的数据加密场景中。
-
限制和适用范围:尽管RSA-AES提供了综合的解决方案,但它的效率可能会因为需要更多的计算资源而降低。此外,它可能不如单独使用RSA或AES提供更高的安全性。
总之,将RSA与AES结合在一起可以提高数据的安全性,特别是在电子商务和其他需要高安全性的场景中。然而,这可能带来额外的成本和处理时间的增加。
2.Python 实现 RSA(数据加密-OAEP) 和 AES(CBC 模式)加密算法
(1)安装 pycryptodome 库
pip install pycryptodome
(2)Python 对文件加密
from Crypto.PublicKey import RSA
from Crypto.Cipher import AES, PKCS1_OAEP
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes
# 生成 RSA 密钥对
def generate_rsa_key_pair(key_size=2048):
key = RSA.generate(key_size)
private_key = key.export_key()
public_key = key.publickey().export_key()
return private_key, public_key
# 使用 RSA 公钥加密对称密钥
def rsa_encrypt_symmetric_key(symmetric_key, public_key):
recipient_key = RSA.import_key(public_key)
cipher_rsa = PKCS1_OAEP.new(recipient_key)
encrypted_symmetric_key = cipher_rsa.encrypt(symmetric_key)
return encrypted_symmetric_key
# 使用 RSA 私钥解密对称密钥
def rsa_decrypt_symmetric_key(encrypted_symmetric_key, private_key):
private_key = RSA.import_key(private_key)
cipher_rsa = PKCS1_OAEP.new(private_key)
symmetric_key = cipher_rsa.decrypt(encrypted_symmetric_key)
return symmetric_key
# 使用对称密钥 AES 加密文件
def aes_encrypt_file(input_file_path, output_file_path, symmetric_key):
chunk_size = 64 * 1024 # 64 KB chunks
iv = get_random_bytes(AES.block_size)
cipher = AES.new(symmetric_key, AES.MODE_CBC, iv)
with open(input_file_path, 'rb') as input_file, \
open(output_file_path, 'wb') as output_file:
output_file.write(iv) # 写入初始化向量
while chunk := input_file.read(chunk_size):
if len(chunk) % AES.block_size != 0:
chunk = pad(chunk, AES.block_size)
encrypted_chunk = cipher.encrypt(chunk)
output_file.write(encrypted_chunk)
# 使用对称密钥 AES 解密文件
def aes_decrypt_file(input_file_path, output_file_path, symmetric_key):
chunk_size = 64 * 1024 # 64 KB chunks
with open(input_file_path, 'rb') as input_file, \
open(output_file_path, 'wb') as output_file:
iv = input_file.read(AES.block_size) # 读取初始化向量
cipher = AES.new(symmetric_key, AES.MODE_CBC, iv)
while chunk := input_file.read(chunk_size):
decrypted_chunk = cipher.decrypt(chunk)
if len(chunk) < chunk_size:
decrypted_chunk = unpad(decrypted_chunk, AES.block_size)
output_file.write(decrypted_chunk)
# 示例使用
private_key, public_key = generate_rsa_key_pair()
# 生成一个对称密钥
symmetric_key = get_random_bytes(32) # AES 256
# 使用 RSA 公钥加密对称密钥
encrypted_symmetric_key = rsa_encrypt_symmetric_key(symmetric_key, public_key)
print(f"Encrypted Symmetric Key: {encrypted_symmetric_key}")
# 使用 RSA 私钥解密对称密钥
decrypted_symmetric_key = rsa_decrypt_symmetric_key(encrypted_symmetric_key, private_key)
print(f"Decrypted Symmetric Key: {decrypted_symmetric_key}")
# AES 加密文件
input_file_path = 'example.txt'
encrypted_file_path = 'encrypted.bin'
decrypted_file_path = 'decrypted.txt'
with open(input_file_path, 'w') as file:
file.write("This is a secret message.")
aes_encrypt_file(input_file_path, encrypted_file_path, symmetric_key)
print(f"File {input_file_path} encrypted to {encrypted_file_path}.")
# AES 解密文件
aes_decrypt_file(encrypted_file_path, decrypted_file_path, symmetric_key)
print(f"File {encrypted_file_path} decrypted to {decrypted_file_path}.")