我正在尝试用 python 解密 Apache Nifi (1.23.1)
flow.xml.gz
(或 flow.json.gz
)文件中的某些值。通过对 Java 文件进行一些修补,我发现了以下信息:
田野 | 价值 |
---|---|
算法 |
|
密码 |
|
,如 CipherPropertyEncryptor.java |
|
,如 CipherPropertyEncryptor.java |
|
盐 |
|
迭代 | 160,000 |
解密值 |
|
当尝试用 Python 编写解密程序时,我使用 https://asecuritysite.com/encryption/aes_gcm2 作为指导。
我有以下代码,结果是
ValueError: MAC check failed
# https://asecuritysite.com/encryption/aes_gcm2
from Crypto.Cipher import AES
import hashlib
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Hash import SHA256, SHA512
# plaintext='Changeit!'
password='1+LFssX4whxz9lOPQ9OS7g4NvQzbCe8j'
salt = b'NiFi Static Salt'
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()
# /home/nifi/nifi/nifi-commons/nifi-security-crypto-key/src/main/java/org/apache/nifi/security/crypto/key/pbkdf2/Pbkdf2DerivedKeyProvider.java says sha512 hmac
# /home/nifi/nifi/nifi-nar-bundles/nifi-cipher-bundle/nifi-cipher-processors/src/main/java/org/apache/nifi/processors/cipher/DecryptContent.java key length bytes 16
key = PBKDF2(password, salt, 16, count=160000, hmac_hash_module=SHA512)
# key = PBKDF2(password, salt, 32, count=160000, hmac_hash_module=SHA256) # from original code example
# 697a84312aac99fbe2315f0637c960352242e26ffd3e2c33c298f06730fffa9687cb0d845f57c1a645 from a real run, should decrypt to Changeit!
# 2242e26ffd3e2c33c298f06730fffa9687cb0d845f57c1a645 cipherbinary from java
# in java, IV in /home/nifi/nifi/nifi-commons/nifi-property-encryptor/src/main/java/org/apache/nifi/encrypt/KeyedCipherPropertyEncryptor.java is 697a84312aac99fbe2315f0637c96035
ciphertext = (b'697a84312aac99fbe2315f0637c96035', b'2242e26ffd3e2c33c2', b'98f06730fffa9687cb0d845f57c1a645')
res = decrypt(ciphertext,key,AES.MODE_GCM)
print ("\n\nDecrypted:\t",res.decode())
Java 与 python AES PBKDF2。为什么输出不同? 看起来也相关,但是没有原始代码,很难理解问题是什么以及如何解决。
如何修复此解密方法以获得正确的值?
Nonce、密文和标签必须进行十六进制解码。此外,实际密文、身份验证标记和随机数的值分配不正确(正确:密文 -> 0x2242...,标记 -> 0x98f0...,随机数 -> 0x697a...)。并且使用 PBKDF2 生成的密钥必须是 32 字节(而不是 16 字节)。
以下代码修复了这些错误,可以正确解密密文:
from Crypto.Cipher import AES
from Crypto.Hash import SHA512
from Crypto.Protocol.KDF import PBKDF2
# plaintext='Changeit!'
password='1+LFssX4whxz9lOPQ9OS7g4NvQzbCe8j'
salt = b'NiFi Static Salt'
def decrypt(ciphertext, key, mode):
(ciphertext, authTag, nonce) = ciphertext
encobj = AES.new(key, mode, nonce)
return(encobj.decrypt_and_verify(ciphertext, authTag))
key = PBKDF2(password, salt, 32, count=160000, hmac_hash_module=SHA512) # 32 bytes key
ciphertext = (
bytes.fromhex('2242e26ffd3e2c33c2'), # actual ciphertext
bytes.fromhex('98f06730fffa9687cb0d845f57c1a645'), # authentication tag
bytes.fromhex('697a84312aac99fbe2315f0637c96035') # nonce
)
res = decrypt(ciphertext, key, AES.MODE_GCM)
print ("\n\nDecrypted:\t",res.decode()) # Decrypted: Changeit!