python-3.xamazon-web-servicesaws-lambdapython-packagingaws-lambda-layers

Unable to import module 'lambda_function': No module named 'Crypto'


I have following python lambda function

lambda_function.py

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad,unpad
import base64

#CBC with Fix IV

data = 'random text to be encrypted decrypted'
key = 'xxx' #16 char for AES128

#FIX IV
iv =  'yyy'.encode('utf-8') #16 char for AES128

def encrypt(data,key,iv):
        data= pad(data.encode(),16)
        cipher = AES.new(key.encode('utf-8'),AES.MODE_CBC,iv)
        return base64.b64encode(cipher.encrypt(data))

def decrypt(enc,key,iv):
        enc = base64.b64decode(enc)
        cipher = AES.new(key.encode('utf-8'), AES.MODE_CBC, iv)
        return unpad(cipher.decrypt(enc),16)

encrypted = encrypt(data,key,iv)
print('encrypted CBC base64 : ',encrypted.decode("utf-8", "ignore"))

decrypted = decrypt(encrypted,key,iv)
print('decrypted data: ', decrypted.decode("utf-8", "ignore"))

def lambda_handler(event, context):
    encrypt(data, key, iv)

I created a lambda function using runtime python 3.12 and created a layer called custom_encrypt_decrypt and added this layer to the lambda as shown below,

enter image description here

When I try to execute the lambda, it throws error,

"Unable to import module 'lambda_function': No module named 'Crypto'"


Firstly, I found that I have to use pycryptodome python library.

How I uploaded this library to lambda

  1. in my local computer I added the library,

    pip install pycryptodome

It added these two folders in my local

enter image description here

  1. I selected both the folders and created a .zip folder.
  2. uploaded zip folder to custom_encrypt_decrypt layer (and layer is already attached to lambda) - Note: pointing to right layer version.
  3. Executed lambda again and getting the same error again n again.

NOTE: If I run this python code locally, it works using same pycryptodome library!


Updates:

There is some serious problem and I don't know what is wrong.

I reduced my lambda code to below,

import json
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad,unpad
import base64

def lambda_handler(event, context):
    # TODO implement
    return {
        'statusCode': 200,
        'body': json.dumps('Hello from Lambda!')
    }

and followed steps suggested by @Roronoa Zoro (for windwos) and now I get below errors

{
  "errorMessage": "Cannot load native module 'Crypto.Cipher._raw_ecb': Not found '_raw_ecb.cpython-312-x86_64-linux-gnu.so', Not found '_raw_ecb.abi3.so', Not found '_raw_ecb.so'",
  "errorType": "OSError",
  "requestId": "",
  "stackTrace": [
    "  File \"/var/lang/lib/python3.12/importlib/__init__.py\", line 90, in import_module\n    return _bootstrap._gcd_import(name[level:], package, level)\n",
    "  File \"<frozen importlib._bootstrap>\", line 1381, in _gcd_import\n",
    "  File \"<frozen importlib._bootstrap>\", line 1354, in _find_and_load\n",
    "  File \"<frozen importlib._bootstrap>\", line 1325, in _find_and_load_unlocked\n",
    "  File \"<frozen importlib._bootstrap>\", line 929, in _load_unlocked\n",
    "  File \"<frozen importlib._bootstrap_external>\", line 994, in exec_module\n",
    "  File \"<frozen importlib._bootstrap>\", line 488, in _call_with_frames_removed\n",
    "  File \"/var/task/lambda_function.py\", line 2, in <module>\n    from Crypto.Cipher import AES\n",
    "  File \"/opt/python/Crypto/Cipher/__init__.py\", line 27, in <module>\n    from Crypto.Cipher._mode_ecb import _create_ecb_cipher\n",
    "  File \"/opt/python/Crypto/Cipher/_mode_ecb.py\", line 35, in <module>\n    raw_ecb_lib = load_pycryptodome_raw_lib(\"Crypto.Cipher._raw_ecb\", \"\"\"\n",
    "  File \"/opt/python/Crypto/Util/_raw_api.py\", line 315, in load_pycryptodome_raw_lib\n    raise OSError(\"Cannot load native module '%s': %s\" % (name, \", \".join(attempts)))\n"
  ]
}

Solution

  • I was facing the same issue after some troubleshooting, I was able to fix the issue.

    Create Zip file in below mentioned path:

    python3 -m venv venv
    source venv/bin/activate
    
    mkdir python
    cd python
    
    pip3 install pycryptodome -t .
    
    cd .. 
    zip -r deployment_name.zip python
    

    Make sure the ZIP file is created for all folder available in python folder Don't miss out any files or folders it may be our main package may be dependent on it.


    For Windows

    mkdir layers
    cd layers
    mkdir python
    cd python
    pip3 install pycryptodome -t ./
    

    It will great if you have Linux Machine or Create an EC2 Instance with Ubuntu AMI and Copy the Content to S3, the you can upload it from S3 bucket to AWS lambda layer directly.

    Update:

    Make Sure to add the layer to lambda My Python version was 3.10 for local and Lambda's python