一、前言

加解密文件是日常安全活动中非常常见的行为,对一个文件做加密通常是为了保护这个文件不被非法获取。

加密算法分为对称加密和非对称加密两种,对称加密算法的优点是加解密速度快,可以用来处理大量的文本数据,缺点是需要保护密钥的安全,最常用的算法是AES;非对称加密算法的优点是加解密使用不同密钥,这样就不存在密钥传输的安全问题,缺点是加解密速度慢,可以用来处理少量文本数据,最常用的算法是RSA。

因此,一个常见的解决方案是使用AES加密文本数据,再使用RSA加密AES的密钥,最后再将结果打包,这样既实现了加解密速度的要求,又实现了密钥传输安全的要求。

二、代码实例

代码中已有明确注释,因此不再做单独的逻辑解释。

#!/usr/bin/python
#-*- coding:utf8 -*-

from Cryptodome.Cipher import AES, PKCS1_OAEP
from Cryptodome.PublicKey import RSA
from Cryptodome.Random import get_random_bytes
from io import BytesIO
import base64
import zlib

# RSA密钥生成函数
def generate():
    new_key = RSA.generate(2048)
    private_key = new_key.exportKey()
    public_key = new_key.publickey().exportKey()

    # 将私钥写入key.pri文件中
    with open('key.pri', 'wb') as f:
        f.write(private_key)
        f.close()
    # 将公钥写入key.pub文件中
    with open('key.pub', 'wb') as f:
        f.write(public_key)
        f.close()

# 加载私钥或公钥,传入一个密钥类型(pri/pub)作为参数
def get_rsa_cipher(keytype):
    # 读取文件
    with open(f'key.{keytype}') as f:
        key = f.read()
        f.close()
    rsakey = RSA.importKey(key)
    # 返回密码对象和RSA密钥的长度
    return (PKCS1_OAEP.new(rsakey), rsakey.size_in_bytes())

# 加密数据函数
def encrypt(plaintext):
    # 将明文数据以bytes类型传入并压缩
    compressed_text = zlib.compress(plaintext)
    # 随机生成一个密钥作为AES使用的密钥
    session_key = get_random_bytes(16)
    cipher_aes = AES.new(session_key, AES.MODE_EAX)
    # 使用AES对压缩过的明文进行加密
    ciphertext, tag = cipher_aes.encrypt_and_digest(compressed_text)
    # 使用RSA公钥将AES密钥进行加密
    cipher_rsa, _ = get_rsa_cipher('pub')
    encrypted_session_key = cipher_rsa.encrypt(session_key)
    # 将解密所需的全部信息打包在msg_payload中(RSA公钥加密后的值、AES密钥、标签、密文)
    msg_payload = encrypted_session_key + cipher_aes.nonce + tag + ciphertext
    # 再使用base64编码,之后保存成encrypted的字符串返回
    encrypted = base64.encodebytes(msg_payload)
    return (encrypted)

# 解密数据函数
def decrypt(encrypted):
    # base64解码之前编码的数据
    encrypted_bytes = BytesIO(base64.decodebytes(encrypted))
    # 读取RSA私钥
    cipher_rsa, keysize_in_bytes = get_rsa_cipher('pri')
    # 读取RSA公钥加密后的值
    encrypted_session_key = encrypted_bytes.read(keysize_in_bytes)
    # 读取AES密钥
    nonce = encrypted_bytes.read(16)
    # 读物标签信息
    tag = encrypted_bytes.read(16)
    # 读取密文
    ciphertext = encrypted_bytes.read()
    # 使用RSA私钥解密AES密钥
    session_key = cipher_rsa.decrypt(encrypted_session_key)
    cipher_aes = AES.new(session_key, AES.MODE_EAX, nonce)
    # 使用AES密钥解密正文
    decrypted = cipher_aes.decrypt_and_verify(ciphertext, tag)
    # 解压为明文消息并返回
    plaintext = zlib.decompress(decrypted)
    return plaintext

if __name__ == '__main__':
    # 调用RSA密钥生成函数
    generate()
    # 以下是加解密这段文字的说明
    plaintext = b'how old are you'
    print(f'the plain text is : {plaintext}')
    encrypted_text = encrypt(plaintext)
    print(f'the encrypted plain text is :\n {encrypted_text}')
    print(f'the decrypted plain text is :\n {decrypt(encrypted_text)}')

三、运行测试

直接执行代码即可:

python xxx.py

huffman解密 python_安全