加密算法(一): AES、RSA、AES 和 RSA混合加密

一、对称加密算法 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)技术,它结合了两者的优点。

  1. 安全性:RSA提供了对称密钥和非对称密钥的安全性。AES则提供了一个强大的数据加密机制。将两者结合使用可以提高安全性,因为它允许接收者根据私钥解密信息,并且确保只有发送者知道自己的公钥。

  2. 处理能力:虽然RSA-AES技术提高了安全性,但它的效率可能不如单独的RSA或AES高。这是因为RSA-AES需要计算大量的乘法和模数来加密数据。相比之下,AES提供了更快的加密速度,特别是在对称密钥情况下。

  3. 应用方面:RSA-AES通常用于提高电子商务的安全性,例如通过使用安全套接层(SSL)协议来保护在线支付过程。这种组合技术还可以用于数字签名、数字证书和更广泛的数据加密场景中。

  4. 限制和适用范围:尽管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}.")

  • 17
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值