2

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:

  1. 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?

  2. Why do I need to provide an authentication tag for decryption with one implementation and not the other?

  3. Is pycryptodomex doing something under the hood to determine the tag?

  • You may be interested in my answer [here](https://stackoverflow.com/a/49244840/589259). It is in Java, but the same principle applies. – Maarten Bodewes Feb 13 '20 at 23:13

2 Answers2

3
  1. GCM without authentication tag is equivalent to CTR mode. (except the + 1 difference in starting counter value)

  2. 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).

  3. See 2.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
Soronbe
  • 906
  • 5
  • 12
  • Can you explain the implication of the +1 difference in starting counter value? Can I use `mode.CTR(nonce)` and get an accurate decrypt? At first glance, it doesn't appear that `PyCA/cryptography` allows for unverified authentication tags. –  Feb 13 '20 at 22:38
  • I can't edit my post, but wanted to note that my colleague mentioned the encrypted file contains some initial padding, the nonce, the encrypted data, and some padding at the end. Is the authentication tag included in those padding values? Again, out of depth so appreciate any feedback. –  Feb 13 '20 at 22:40
  • I don't think #1 fully catches the full difference, see my answer [here](https://stackoverflow.com/a/49244840/589259), and at least notice the expansion to 16 bytes and the +2 rather than +1. – Maarten Bodewes Feb 13 '20 at 23:14
0

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?