You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Python通过AWS非对称密钥实现大文件加密与解密

使用Python结合AWS非对称密钥加密解密大文件

由于AWS KMS非对称密钥(如RSA、ECC)的加密 payload 存在大小限制(例如RSA 2048位最多加密245字节),直接加密大文件不可行,因此必须采用信封加密方案,核心逻辑如下:

核心思路

  1. 生成一次性对称密钥(如AES-256),用它加密大文件(对称加密效率远高于非对称加密)
  2. 使用AWS KMS的非对称公钥加密上述对称密钥
  3. 保存加密后的文件、加密后的对称密钥及加密所需的初始化向量(IV)
  4. 解密时,先用AWS KMS的非对称私钥解密对称密钥,再用该密钥解密大文件

前置准备

  • 安装依赖:pip install boto3 cryptography
  • 配置AWS凭证:通过环境变量、~/.aws/credentials 文件或IAM角色授权
  • 拥有AWS KMS非对称密钥对,且当前身份具备 kms:Encrypt(加密)和 kms:Decrypt(解密)权限

加密实现代码

import boto3
import os
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend

def encrypt_large_file(kms_key_id, input_file_path, output_file_path):
    # 初始化KMS客户端
    kms_client = boto3.client('kms')
    
    # 生成AES-256对称密钥和16字节IV(CBC模式)
    aes_key = os.urandom(32)
    iv = os.urandom(16)
    
    # 用AWS KMS非对称公钥加密AES密钥
    encrypted_aes_key = kms_client.encrypt(
        KeyId=kms_key_id,
        Plaintext=aes_key,
        EncryptionAlgorithm='RSAES_OAEP_SHA_256'
    )['CiphertextBlob']
    
    # 用AES-CBC加密大文件
    cipher = Cipher(algorithms.AES(aes_key), modes.CBC(iv), backend=default_backend())
    encryptor = cipher.encryptor()
    
    with open(input_file_path, 'rb') as infile, open(output_file_path, 'wb') as outfile:
        # 先写入加密后的AES密钥长度、密钥本身、IV
        outfile.write(len(encrypted_aes_key).to_bytes(4, byteorder='big'))
        outfile.write(encrypted_aes_key)
        outfile.write(iv)
        
        # 分块读取加密(避免加载整个大文件到内存)
        chunk_size = 64 * 1024
        while chunk := infile.read(chunk_size):
            # 填充到16字节倍数(CBC模式要求)
            if len(chunk) % 16 != 0:
                chunk += b' ' * (16 - len(chunk) % 16)
            outfile.write(encryptor.update(chunk))
        outfile.write(encryptor.finalize())

# 使用示例
# encrypt_large_file('arn:aws:kms:us-east-1:123456789012:key/your-key-id', 'input.txt', 'encrypted.bin')

解密实现代码

def decrypt_large_file(kms_key_id, input_file_path, output_file_path):
    kms_client = boto3.client('kms')
    
    with open(input_file_path, 'rb') as infile, open(output_file_path, 'wb') as outfile:
        # 读取加密后的AES密钥长度和密钥
        encrypted_key_len = int.from_bytes(infile.read(4), byteorder='big')
        encrypted_aes_key = infile.read(encrypted_key_len)
        # 读取IV
        iv = infile.read(16)
        
        # 用AWS KMS非对称私钥解密AES密钥
        decrypted_aes_key = kms_client.decrypt(
            CiphertextBlob=encrypted_aes_key,
            KeyId=kms_key_id,
            EncryptionAlgorithm='RSAES_OAEP_SHA_256'
        )['Plaintext']
        
        # 用AES-CBC解密文件
        cipher = Cipher(algorithms.AES(decrypted_aes_key), modes.CBC(iv), backend=default_backend())
        decryptor = cipher.decryptor()
        
        chunk_size = 64 * 1024
        while chunk := infile.read(chunk_size):
            outfile.write(decryptor.update(chunk))
        outfile.write(decryptor.finalize())
        # 去除填充的空格
        outfile.seek(-1, os.SEEK_END)
        while outfile.read(1) == b' ':
            outfile.seek(-2, os.SEEK_CUR)
        outfile.truncate()

# 使用示例
# decrypt_large_file('arn:aws:kms:us-east-1:123456789012:key/your-key-id', 'encrypted.bin', 'decrypted.txt')

关键注意事项

  • 加密模式选择:如果需要完整性校验,推荐使用AES-GCM模式(自带认证标签),替换上述代码中的CBC模式即可,避免文件被篡改
  • 权限控制:确保IAM策略仅允许必要的身份访问KMS密钥,遵循最小权限原则
  • 密钥存储:加密后的对称密钥和IV可直接附加在加密文件头部(如示例所示),无需单独存储,简化管理
  • 分块处理:代码采用分块读写,避免大文件占用过多内存,适用于GB级文件

内容的提问来源于stack exchange,提问作者gregory jithin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 05:50:34