Java 与 python AES PBKDF2

问题描述 投票:0回答:1

我正在尝试用 python 解密 Apache Nifi (1.23.1)

flow.xml.gz
(或
flow.json.gz
)文件中的某些值。通过对 Java 文件进行一些修补,我发现了以下信息:

中所述 中所述
田野 价值
算法
NIFI_PBKDF2_AES_GCM_256
密码
1+LFssX4whxz9lOPQ9OS7g4NvQzbCe8j
binary
,如 CipherPropertyEncryptor.java
697a84312aac99fbe2315f0637c960352242e26ffd3e2c33c298f06730fffa9687cb0d845f57c1a645
cipherbinary
,如 CipherPropertyEncryptor.java
2242e26ffd3e2c33c298f06730fffa9687cb0d845f57c1a645
NiFi Static Salt
迭代 160,000
解密值
Changeit!

当尝试用 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。为什么输出不同? 看起来也相关,但是没有原始代码,很难理解问题是什么以及如何解决。

如何修复此解密方法以获得正确的值?

python java encryption aes pbkdf2
1个回答
0
投票

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!     
© www.soinside.com 2019 - 2024. All rights reserved.