I use the AES method to encrypt a sentance called from a txt file. I used the GCM Mode and created a specific key too. Everything is working (the code is below).
from Crypto.Cipher import AES
from Crypto.Protocol.KDF import scrypt
from Crypto.Util.number import long_to_bytes
number = 1
flag = open("sentance.txt", "rb").read()
key = scrypt(long_to_bytes(number), b"code", 32, N = 2 ** 10, r = 8, p = 1)
HexMyKey = key.hex()
cipher = AES.new(key, AES.MODE_GCM)
ciphertext, tag = cipher.encrypt_and_digest(flag)
enc = cipher.nonce + ciphertext + tag
HexEncryptedOriginalMessage = enc.hex()
I try to implement the decryption process, that is to say I only have the key (HexMyKeyvalue) and the encrypted message (HexEncryptedOriginalMessage value) and I want to decrypt it.
But the thing is that I miss something ..
I wrote the code below but I have that error message.
TypeError: decrypt_and_verify() missing 1 required positional argument: 'received_mac_tag
from Crypto.Cipher import AES
from Crypto.Protocol.KDF import scrypt
from Crypto.Util.number import long_to_bytes
key = bytes.fromhex(HexMykey)
data = bytes.fromhex(HexEncryptedOriginalMessage)
cipher = AES.new(key, AES.MODE_GCM)
dec = cipher.decrypt_and_verify(data)
Do you know how I could decrypt that encrypted original message ?
Any help would be greatly appreciated !
PyCryptodome has a good documentation. The GCM example there uses JSON for concatenating/separating nonce, ciphertext, and tag, but the principle is the same and can easily be applied to your code.
Since you are using the implicitly derived nonce, be aware that PyCryptodome applies a 16 bytes nonce. Note, however, that the recommendation for GCM is a 12 bytes nonce (s. here, Note section).
The following decryption example uses a key and ciphertext created with the code you posted for encryption:
from Crypto.Cipher import AES
HexMyKey = '6f9b706748f616fb0cf39d274638ee29813dbad675dd3d976e80bde4ccd7546a'
HexEncryptedOriginalMessage = '6b855acc799213c987a0e3fc4ddfb7719c9b87fcf0a0d35e2e781609143b6e2d8e743cf4aea728002a9fc77ef834'
key = bytes.fromhex(HexMyKey)
data = bytes.fromhex(HexEncryptedOriginalMessage)
cipher = AES.new(key, AES.MODE_GCM, data[:16]) # nonce
try:
dec = cipher.decrypt_and_verify(data[16:-16], data[-16:]) # ciphertext, tag
print(dec) # b'my secret data'
except ValueError:
print("Decryption failed")
If authentication fails, decrypt_and_verify()
generates a ValueError
.
PyCryptodome also allows for GCM decryption without prior authentication:
cipher = AES.new(key, AES.MODE_GCM, data[:16]) # nonce
dec = cipher.decrypt(data[16:-16]) # ciphertext
print(dec) # b'my secret data'
However, this should not be done for GCM for security reasons, since a ciphertext is only trustworthy after successful authentication.
Furthermore, the encryption and decryption codes are somewhat inconsistent in that the encryption uses scrypt as the key derivation function and the decryption uses the derived key directly. Normally, one would expect that the key is also derived during decryption. Possibly you take this shortcut only for testing purposes.