如何在AWS Lambda(Python)中实现SHA-512+AES-256加密及解决依赖报错
问题解决:AWS Lambda中PyCryptodomex导入原生模块失败
核心原因
PyCryptodome包含原生C扩展模块,你在本地(非Linux x86_64环境)安装的依赖包,其编译生成的二进制文件(.so)与AWS Lambda运行的Amazon Linux 2 x86_64环境不兼容,导致Lambda无法找到匹配的原生模块。
解决方案
方案1:用Docker模拟Lambda环境构建依赖
这是最可靠的方式,确保依赖包是针对Lambda环境编译的:
- 拉取对应Python版本的AWS Lambda官方构建镜像(以Python 3.9为例):
docker pull public.ecr.aws/sam/build-python3.9 - 创建临时目录,在容器内将依赖安装到Lambda Layer要求的目录结构:
mkdir -p lambda-layer/python/lib/python3.9/site-packages docker run --rm -v "$PWD/lambda-layer:/layer" public.ecr.aws/sam/build-python3.9 \ pip install pycryptodomex -t /layer/python/lib/python3.9/site-packages --no-user - 进入
lambda-layer目录,打包为符合Layer要求的zip文件:cd lambda-layer zip -r pycryptodomex-layer.zip python/ - 将该zip包上传为AWS Lambda Layer,再关联到你的Lambda函数即可。
方案2:改用兼容性更好的加密库
如果不想处理原生模块的兼容性问题,可以替换为cryptography库(同样需在Lambda环境下打包,但兼容性更稳定),该库在Lambda运行环境中无需额外处理原生模块适配。
额外提醒:匹配你的加密模式需求
你提到需要使用AES-256 CBC模式,但当前代码中使用的是AES.MODE_GCM,以下是调整为CBC模式的示例代码:
from base64 import b64encode, b64decode import hashlib from Cryptodome.Cipher import AES from Cryptodome.Random import get_random_bytes def encrypt(plain_text, password): # 生成盐值和CBC所需的初始化向量IV salt = get_random_bytes(16) iv = get_random_bytes(AES.block_size) # 通过Scrypt生成256位密钥 private_key = hashlib.scrypt( password.encode(), salt=salt, n=2**14, r=8, p=1, dklen=32) # CBC模式需要明文长度为块大小的倍数,执行PKCS7填充 padding_length = AES.block_size - len(plain_text.encode()) % AES.block_size padded_plaintext = plain_text.encode() + bytes([padding_length]) * padding_length # 初始化加密器并加密 cipher = AES.new(private_key, AES.MODE_CBC, iv) cipher_text = cipher.encrypt(padded_plaintext) return { 'cipher_text': b64encode(cipher_text).decode('utf-8'), 'salt': b64encode(salt).decode('utf-8'), 'iv': b64encode(iv).decode('utf-8') } def decrypt(enc_dict, password): # 解码base64格式的参数 salt = b64decode(enc_dict['salt']) iv = b64decode(enc_dict['iv']) cipher_text = b64decode(enc_dict['cipher_text']) # 重新生成密钥 private_key = hashlib.scrypt( password.encode(), salt=salt, n=2**14, r=8, p=1, dklen=32) # 初始化解密器并解密 cipher = AES.new(private_key, AES.MODE_CBC, iv) decrypted_padded = cipher.decrypt(cipher_text) # 去除PKCS7填充 padding_length = decrypted_padded[-1] decrypted = decrypted_padded[:-padding_length].decode('utf-8') return decrypted
内容的提问来源于stack exchange,提问作者Anirudh B M
相关产品推荐
相关产品推荐

