Search code examples
pythonencryptionaespycryptopycryptodome

PyCryptodome AES, 'EcbMode' object has no attribute 'encrypt_and_digest'


I am using Pycharm Text Editor and PyCryptodome Library for encryption of message using Advanced Encryption Standard (AES). It is also one of the majorly used Symmetric Encryption Algorithm. My code of AES Encryption was stated below:

from Crypto.Cipher import AES
key = os.urandom(16)
cipher = AES.new(key, AES.MODE_ECB)
ciphertext, tag = cipher.encrypt_and_digest(message)

And I am encountering the error:-

AttributeError: 'EcbMode' object has no attribute 'encrypt_and_digest

at line:-

ciphertext, tag = cipher.encrypt_and_digest(message)

I have tried uninstalling the module a couple of times but the error persists. Pycharm does not mark the line with red underscores and I can use ctrl-click to go into the source and see that the encrypt_and_digest() function exists.

My question is:-

Why can't the code go through the compiler? Is there another module in python that I can use to perform AES encryption?


Solution

  • From Error we can see that encrypt_and_digest() attribute is not available in ECB (Electronic Code Book) Mode of AES Encryption. So, there are two Solution for your query let's have a look at one by one:-

    1. By Changing Mode:-

    By Changing mode to modern modes we can use encrypt_and_digest() module. Basically encrypt_and_digest() module is combination of encrypt() and digest() Module.

    • encrypt():- This module used to Encrypt your Message
    • digest():- This module used to Generate MAC Tag of Message
    # List of 'Modern Modes' was given below:-
    1. MODE_EAX
    2. MODE_CCM
    3. MODE_SIV
    4. MODE_GCM
    5. MODE_OCB
    

    Code for the given Scenario Using EAX Mode was stated below:-

    # Import all the Important Libraries
    from Crypto.Cipher import AES
    import os
    
    # 'pad_message()' function declaration for padding purpose.
    # Because 'message' length should be always multiple of '16'
    def pad_message(message):
      while len(message) % 16 != 0:
        message = message + " "
      return message
    
    # Initialization of 'Key' and 'Message'
    key = os.urandom(16)
    message = input("Enter your Message for AES Encryption:- ")
    
    # If the length of the message is not multiple of '16' then pad it
    message = pad_message(message)
    
    # Print Message, Key and Length of Message before Encryption Process
    print("\nMessage:-", message)
    print("Key:-", key)
    print("Length of the Message:-", len(message))
    
    # Declare New module for AES Encryption in 'EAX' Mode
    cipher = AES.new(key, AES.MODE_EAX)
    
    # Encrypt 'Message' and Generate 'MAC Tag' Using 'encrypt_and_digest()' method
    cipher_text, mac_tag = cipher.encrypt_and_digest(message.encode('utf-8'))
    
    # Print Encrypted Message 
    print("\nEncryption of Message Using AES:-", cipher_text)
    print("MAC Tag of our Encrypted Message is:-", mac_tag)
    
    # Output of Above Code:-
    Enter your Message for AES Encryption:- Stack Overflow
    
    Message:- Stack Overflow  
    Key:- b'\xf1\x9a\xc1\x12\xdcI7\xc8\xe4\xcf\x1e5\xe4\x93i\xc4'
    Length of the Message:- 16
    
    Encryption of Message Using AES:- b'\x97\x0e+\xcb^\x82\xeelhs2_\x90m\x1c+'
    MAC Tag of our Encrypted Message is:- b'c!\xb2\xf4\x82\xceT3\x0cM1\x04\x87(y?'
    

    2. Without Changing Mode:-

    If you want to Encrypt Using ECB (Electronic Code Book) Mode. then we can Use encrypt() and hex() module.

    Code for the given Scenario Using ECB Mode was stated below:-

    # Import all the Important Libraries
    from Crypto.Cipher import AES
    import os
    
    # 'pad_message()' function declaration for padding purpose.
    # Because 'message' length should be always multiple of '16'
    def pad_message(message):
      while len(message) % 16 != 0:
        message = message + " "
      return message
    
    # Initialization of 'Key' and 'Message'
    key = os.urandom(16)
    message = input("Enter your Message for AES Encryption:- ")
    
    # If the length of the message is not multiple of '16' then pad it
    message = pad_message(message)
    
    # Print Message, Key and Length of Message before Encryption Process
    print("\nMessage:-", message)
    print("Key:-", key)
    print("Length of the Message:-", len(message))
    
    # Declare New module for AES Encryption in 'ECB (Electronic Codebook)' Mode
    cipher = AES.new(key, AES.MODE_ECB)
    
    # Encrypt 'Message'
    cipher_text  = cipher.encrypt(message.encode('utf-8'))
    
    # Print Encrypted Message 
    print("\nEncryption of Message Using AES:-", cipher_text)
    print("Hex of Cipher Text:-", cipher_text.hex())
    
    # Verify by decrypting Cipher Text whether you are recieving same message or not
    decrypted_message = cipher.decrypt(cipher_text)
    print("\nDecryption of Cipher Text Using AES:-", decrypted_message)
    
    # Output of Above Code:-
    Enter your Message for AES Encryption:- Stack Overflow
    
    Message:- Stack Overflow  
    Key:- b'\x94\x88o\xf0\x8f\xbe\xec\x0e\x1e\xdf\x06A\xdf<\xbe\xe3'
    Length of the Message:- 16
    
    Encryption of Message Using AES:- b'\xf6c)\xee\xea\x13\xdcX\x9c\x06E\x82~{c\xc6'
    Hex of Cipher Text:- f66329eeea13dc589c0645827e7b63c6
    
    The decryption of Cipher Text Using AES:- b'Stack Overflow  
    

    Hope this Solution helps you.