Tool that decrypts Apache NiFi {enc} passwords
Find a file
2026-05-11 00:23:51 +01:00
LICENSE Initial commit 2026-05-10 17:35:32 +01:00
nifi-decrypt.py Fix imports 2026-05-11 00:23:51 +01:00
README.md Initial import 2026-05-10 17:40:20 +01:00
requirements-minimal.txt Initial import 2026-05-10 17:40:20 +01:00
requirements.txt Initial import 2026-05-10 17:40:20 +01:00

nifi-decrypt

Recover plaintext sensitive properties from Apache NiFi flow files.

A Python reimplementation of NiFi's internal PropertyEncryptor (covering both the legacy and modern KDF schemes) so you can decrypt enc{...} values from flow.xml.gz and flow.json.gz without standing up a JVM or running the official encrypt-config toolkit. This tool was totally vibe coded, so take it with a grain of salt.

Use cases

  • Pentesting / red team engagements where you've recovered NiFi config files and want to extract secrets without running NiFi itself.
  • Disaster recovery when you've lost access to a NiFi instance but still hold the flow file and nifi.sensitive.props.key.
  • Migration / audit scenarios where you need to inspect what credentials a flow is referencing.

Scope and ethics

This tool only decrypts data when you already possess the symmetric key (nifi.sensitive.props.key). It does not break NiFi's encryption — it just performs the same decryption NiFi would perform if it were running. Use it on systems you own or are authorized to assess.

Supported algorithms

All values of nifi.sensitive.props.algorithm from NiFi 1.6 through 1.x:

Algorithm Notes
NIFI_PBKDF2_AES_GCM_256 Default since NiFi 1.14
NIFI_PBKDF2_AES_GCM_128
NIFI_ARGON2_AES_GCM_256 Requires argon2-cffi
NIFI_ARGON2_AES_GCM_128 Requires argon2-cffi
NIFI_BCRYPT_AES_GCM_256 Requires bcrypt
NIFI_BCRYPT_AES_GCM_128 Requires bcrypt
NIFI_SCRYPT_AES_GCM_256
NIFI_SCRYPT_AES_GCM_128
PBEWITHMD5AND256BITAES-CBC-OPENSSL Legacy, pre-1.14
PBEWITHMD5AND128BITAES-CBC-OPENSSL Legacy

Both flow.xml.gz and flow.json.gz are supported, gzipped or plain.

Install

git clone https://github.com/<you>/nifi-decrypt
cd nifi-decrypt
pip install -r requirements.txt

If you know your target uses PBKDF2 or the legacy scheme (the most common cases), requirements-minimal.txt is enough and avoids pulling in argon2-cffi and bcrypt.

Usage

The simplest invocation: pass the flow file and nifi.properties. The script reads the key and algorithm out of the properties file automatically.

python3 nifi_decrypt.py /path/to/flow.xml.gz --properties /path/to/nifi.properties

If you only have the key string (e.g. lifted from somewhere other than the canonical nifi.properties):

python3 nifi_decrypt.py flow.xml.gz --key 'TUHh+YHA30zmdlcA8xq/elNBLPkO03Nl'

The default algorithm when --key is used (without --algorithm) is NIFI_PBKDF2_AES_GCM_256, since that is the NiFi 1.14+ default.

Other options

--algorithm, -a    Override the algorithm (e.g. NIFI_ARGON2_AES_GCM_256)
--format, -f       Force a parser: auto (default), xml, json, regex
--show-blob        Print the full enc{...} hex along with each plaintext

--format regex skips structural parsing and just scans for enc{...} patterns. Useful if you have a custom or partially-corrupted flow file that breaks the XML/JSON parser.

Caveats

Bootstrap-protected keys. If your nifi.properties shows nifi.sensitive.props.key.protected=aes/gcm/256 (or similar), the key value itself is encrypted with the bootstrap root key from bootstrap.conf (nifi.bootstrap.sensitive.key). The script detects this and fails with a clear error. You'll need to unwrap the bootstrap layer first (different format, raw 256-bit key, no PBKDF2). PRs welcome.

NiFi 2.x. The script targets the 1.x scheme. NiFi 2.x dropped flow.xml.gz in favor of flow.json.gz but the encryption inside enc{...} appears to be the same scheme. It hasn't been tested against a real 2.x flow file — if you run into issues, please open an issue with a redacted sample.

Format detection edge cases. XML vs JSON is sniffed from the first non-whitespace byte. If your file has a BOM or leading whitespace that confuses this, force the parser with --format xml or --format json.

Verification

The script's PBKDF2 implementation has been verified end-to-end against a real flow.xml.gz blob from a NiFi 1.21 instance. The other three modern KDFs and the legacy CBC path have been round-trip tested against synthetic samples encrypted with the same logic. If you run this against real samples encrypted with Argon2/bcrypt/scrypt, please consider sending an (anonymized) test vector — additional ground-truth coverage is always welcome.

License

MIT.