pythonencryptionapache-nifiaes-gcmpycryptodome

ValueError: MAC check failed when using PyCryptodome to decrypt data coming from NiFi


Can someone help me with this problem:

I am encrypting a JSON in NiFi with AES_GCM algorithm and using a KDF PBKDF2. The idea is to decrypt this JSON with a python script using PyCryptodome.

The following code is an attempt to see if the NiFi encrypted message can be decrypted:

import base64
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Cipher import AES

# Key used in NiFi to encrypt the JSON
key = '-JaNcRfUjXn2r5u8'

# Result value after the EncryptContent processor encrypts 
# the JSON: {"id":"123", "name":"Ronald"}
value = 'nTJuV9l9uQJrWv2HXD37PE5pRmlTQUxUg7ir0oDxuxSnmuqZpbUfVk5pRmlJVn1yT10SdXKjobe9o/QHybJqwhPgCifGz2yiY9JICGehICb/zEsYUivERcMKhg=='

decodeValue = base64.b64decode(value)

salt = decodeValue[:16]
IV = decodeValue[24:40]
dataToDecrypt = decodeValue[46:-16]
tag = decodeValue[-16:]

mainKey = PBKDF2(key, salt)

cipher = AES.new(mainKey, AES.MODE_GCM, IV)
cipher.update(salt)

decryptedData = cipher.decrypt_and_verify(dataToDecrypt, tag)

print(decryptedData)

I understand that in NiFi with NIFI_PBKDF2_AES_GCM_128 encryption the cipher text output consists of the salt (16-byte length), followed by the salt delimiter, UTF-8 string “NiFiSALT” (0x4E 69 46 69 53 41 4C 54) and then the IV, followed by the IV delimiter, UTF-8 string “NiFiIV” (0x4E 69 46 69 49 56), followed by the cipher text, followed by the autehnticaion tag (16-byte length), but when trying to run the above script using this structure, I get the following error:

Traceback (most recent call last):
  File "/home/ronald/anaconda3/envs/Quind/lib/python3.10/code.py", line 90, in runcode
    exec(code, self.locals)
  File "<input>", line 4, in <module>
  File "/home/ronald/anaconda3/envs/Quind/lib/python3.10/site-packages/Crypto/Cipher/_mode_gcm.py", line 567, in decrypt_and_verify
    self.verify(received_mac_tag)
  File "/home/ronald/anaconda3/envs/Quind/lib/python3.10/site-packages/Crypto/Cipher/_mode_gcm.py", line 508, in verify
    raise ValueError("MAC check failed")
ValueError: MAC check failed

I don't understand why the authentication tag check fails.


Solution

  • Decryption fails for two reasons:

    With these changes, authentication and decryption is successful and decryptedData is b'{"id": "123", "name": "Ronald"}'.


    Note that for GCM the length 16 bytes is allowed for the nonce/IV, but the recommended length is 12 bytes. But maybe a change is beyond your control.