AES GCM (Python) with PBKDF2AES GCM (Galois Counter Mode) is a stream cipher mode for AES. It is based on the CTR mode, but is converted into a stream cipher. This provides low latency in the encryption/decryption process, and which is fast to process. As it is a stream cipher, it does not require padding. Along with this it integrates AEAD (Authenticated Encryption with Associated Data) for the authentication of the message. With AES-GCM, we have an encryption key (normally 128 bits or 256 bits) and a message, and then generate the cipher, a random nonce, and an authentication tag (and which is a message authentication code (MAC)). The tag helps authenticate the message. In this case we will generate a 256-bit AES encryption key using PBKDF2, and using a random salt for the password [With SHA-256 password]. |
Code
In the following, we will take a password and then generate a 256-bit key by taking a SHA-256 PBKDF2 hash of the password. An outline of the code is:
from Crypto.Cipher import AES import hashlib import sys import binascii from Crypto.Protocol.KDF import PBKDF2 from Crypto.Hash import SHA256 from Crypto.Random import get_random_bytes plaintext='hello how are you?' password='qwerty123' if (len(sys.argv)>1): plaintext=(sys.argv[1]) if (len(sys.argv)>2): password=(sys.argv[2]) def encrypt(plaintext,key, mode): encobj = AES.new(key, AES.MODE_GCM) ciphertext,authTag=encobj.encrypt_and_digest(plaintext) return(ciphertext,authTag,encobj.nonce) def decrypt(ciphertext,key, mode): (ciphertext, authTag, nonce) = ciphertext encobj = AES.new(key, mode, nonce) return(encobj.decrypt_and_verify(ciphertext, authTag)) key = hashlib.sha256(password.encode()).digest() salt = get_random_bytes(32) key = PBKDF2(password, salt, 32, count=1000000, hmac_hash_module=SHA256) print("GCM Mode: Stream cipher and authenticated") print("\nMessage:\t",plaintext) print("Password:\t\t",password) ciphertext = encrypt(plaintext.encode(),key,AES.MODE_GCM) print("Salt:\t\t",binascii.hexlify(salt)) print("Cipher:\t\t",binascii.hexlify(ciphertext[0])) print("Auth Msg:\t",binascii.hexlify(ciphertext[1])) print("Nonce:\t\t",binascii.hexlify(ciphertext[2])) res= decrypt(ciphertext,key,AES.MODE_GCM) print ("\n\nDecrypted:\t",res.decode())
A sample run gives:
GCM Mode: Stream cipher and authenticated Message: hello how are you? Password: qwerty123 Salt: b'cd2261c94f395837ec313c50bbeaaef09555d4725eaa19f3c4ee868a8362d6ba' Cipher: b'17cb2d75efffba096bf8af270b2aab0e8220' Auth Msg: b'63a67a54d98c14059521776ee1c0ba0e' Nonce: b'866e0a3d8adddd2673408901ef92276d' Decrypted: hello how are you?