Reputation:
I will start with a disclaimer that I am out of my depth here. A colleague was showing me a decryption routine he wrote with pycryptodomex
. He had an encrypted file, a key, and a nonce (extracted from the file). He was able to decrypt the file contents in a very straight forward way.
c = Crypto.Cipher.AES.new(key, AES.MODE_GCM, nonce)
c.decrypt(encrypted_data)
You can see a similar implementation in the pycryptodome test for GCM:
cipher = AES.new(self.key_128, AES.MODE_GCM, nonce=self.nonce_96)
pt = get_tag_random("plaintext", 16 * 100)
ct = cipher.encrypt(pt)
cipher = AES.new(self.key_128, AES.MODE_GCM, nonce=self.nonce_96)
pt2 = cipher.decrypt(ct)
Unfortunately, pycryptdomex
is an additional dependency that I would need to carry around and I am looking to avoid this. I have a base installation of Anaconda, which brings with it the pyCrypto and pyCA/cryptography packages. It appears that pycryptodomex
is a fork of pyCrytpo, which didn't have a stable GCM implementation to begin with. When I look at the implementation for PyCA/cryptography
, it looks straight forward:
cipher = Cipher(algorithms.AES(key), modes.GCM(nonce), backend=default_backend())
d = cipher.decryptor()
But when we want to decrypt content we have to call finalize_with_tag
and produce an authentication tag:
d.update(encrypted_data) + d.finalize_with_tag(tag)
Unfortunately, I don't have an authentication tag nor do I know where to find it. I can't set the value to None as there is a minimum length requirement. I'm also not sure why I need to produce an authentication tag in the first place for AES GCM decryption with PyCA/Cryptography
but I do not need to produce a tag when decrypting with the pycryptodomex
. I'm ultimately looking for clarity on the following:
Is it possible to implement AES/GCM decryption with the Anaconda PyCA/cryptography
package if I only have access to the key, nonce, and encrypted data?
Why do I need to provide an authentication tag for decryption with one implementation and not the other?
Is pycryptodomex
doing something under the hood to determine the tag?
Upvotes: 3
Views: 6341
Reputation: 926
GCM without authentication tag is equivalent to CTR mode. (except the + 1 difference in starting counter value)
Calling decrypt does not verify the tag (as far as I know). You can test this yourself by altering the ciphertext just one byte. It will decrypt just fine (to a plaintext that is off by one byte). Use decrypt_and_verify
(see test_invalid_mac
test).
See 2.
Upvotes: 4
Reputation: 13
Apologies as I can't reply to comments. Is it possible to derive the tag from the decrypted data after decryption? This PR associated with PyCA/cryptography
seems to imply the exact scenario considered here.
According to the GCM spec (section 7.2: “Algorithm for the Authenticated Decryption Function”), the tag itself is not needed until the ciphertext has been decrypted.
Does calling d.update(encrypted_data)
decrypt data successfully and d.finalize()
is only needed to verify the integrity of the data?
Upvotes: 0