Andy LoPresto created NIFI-7344:
-----------------------------------
Summary: Flowfile content viewer appends extra bytes to cipher text
Key: NIFI-7344
URL: https://issues.apache.org/jira/browse/NIFI-7344
Project: Apache NiFi
Issue Type: Bug
Components: Core UI, Security
Affects Versions: 1.11.4, 1.12.0
Reporter: Andy LoPresto
While investigating other issues with encryption services, I had serious
difficulty decrypting some content that had been _encrypted_ in NiFi due to
cipher pad block errors (almost always indicate the use of the wrong key or the
application of a key to the wrong cipher text) and block size errors (indicate
invalid cipher text length).
Through manual analysis, I found that when data is encrypted with
{{EncryptContent}}, the data is encrypted correctly and the right bytes are
written to the content flowfile. In this case, using the following values, the
output should always be 139 bytes. The flowfile size attribute indicates that
correctly, and downloading the flowfile content is exactly 139 bytes. However,
viewing the content in the embedded content viewer results in 140 bytes,
introducing a trailing {{0x10}} byte that should not be there.
So far I have only observed this using the {{Bcrypt}} KDF, and not using the
{{PBKDF2}} KDF. I will continue to investigate if other KDFs influence this
outcome.
For plaintext or JSON/XML content, this is a trivial bug. However, when it
silently modifies binary cipher text, this is a critical, near blocker, issue.
*Plaintext*: \{{This is a plaintext message generated at
${now():format('YYYY-MM-dd HH:mm:ss.SSS Z')}. }} -> Resolves to "This is a
plaintext message generated at 2020-04-08 20:11:44.743 Z. " which is *68* bytes
in UTF-8.
*KDF*: Bcrypt
Encryption Method: AES-CBC
Password: thisIsABadPassword
The resulting cipher text should be 139 bytes (29 bytes of Bcrypt salt, 8 bytes
of NiFi salt delimiter, 16 bytes of IV, 6 bytes of NiFi IV delimiter, and 80
bytes of cipher text [see below for explanation]).
Cipher text length calculation for AES-CBC:
{code:java}
int plaintextBlockLength = Math.ceil(plaintext.length() / 16.0)
boolean plaintextIsExactBlockMultiple = plaintext.length() % 16 == 0
int cipherTextLength = (plaintextIsExactBlockMultiple ? plaintextBlockLength +
1 : plaintextBlockLength) * 16{code}
Given the above formula, a plaintext of length 68 requires 5 blocks, but is not
an even multiple of 16, so does not require an additional padding block.
Rather, 80 bytes (5 * 16) is used.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)