NiFi执行脚本加密json [英] NiFi execute script encrypt json
问题描述
你好,关于这个问题:
没有 try catch:
Without the try catch:
基本上它会尝试执行以下脚本:
Basically it tries to execute the following script:
import javax.crypto.Cipher
import javax.crypto.SecretKey
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
import java.nio.charset.StandardCharsets
FlowFile flowFile = session.get()
if (!flowFile) {
return
}
try {
// Get the raw values of the attributes
String normalAttribute = flowFile.getAttribute('Normal Attribute')
String sensitiveAttribute = flowFile.getAttribute('Sensitive Attribute')
// Instantiate an encryption cipher
// Lots of additional code could go here to generate a random key, derive a key from a password, read from a file or keyring, etc.
String keyHex = "0123456789ABCDEFFEDCBA9876543210" // * 2 for 256-bit encryption
SecretKey key = new SecretKeySpec(keyHex.getBytes(StandardCharsets.UTF_8), "AES")
IvParameterSpec iv = new IvParameterSpec(keyHex[0..<16].getBytes(StandardCharsets.UTF_8))
Cipher aesGcmEncCipher = Cipher.getInstance("AES/GCM/NoPadding", "BC")
aesGcmEncCipher.init(Cipher.ENCRYPT_MODE, key, iv)
String encryptedNormalAttribute = Base64.encoder.encodeToString(aesGcmEncCipher.doFinal(normalAttribute.bytes))
String encryptedSensitiveAttribute = Base64.encoder.encodeToString(aesGcmEncCipher.doFinal(sensitiveAttribute.bytes))
// Add a new attribute with the encrypted normal attribute
flowFile = session.putAttribute(flowFile, 'Normal Attribute (encrypted)', encryptedNormalAttribute)
// Replace the sensitive attribute inline with the cipher text
flowFile = session.putAttribute(flowFile, 'Sensitive Attribute', encryptedSensitiveAttribute)
session.transfer(flowFile, REL_SUCCESS)
} catch (Exception e) {
log.error("There was an error encrypting the attributes: ${e.getMessage()}")
session.transfer(flowFile, REL_FAILURE)
}
推荐答案
该脚本是作为未经测试(且无法工作)的模板提供的,用于演示 ExecuteScript
在特定用例中的功能.正如@daggett 指出的那样,在调用另一个 #doFinal()
之前,密码实例需要再次成为 #init()
,因为 G/CM 密码会计算并应用身份验证标签密文.
That script was provided as an untested (and non-working) template to demonstrate the capabilities of ExecuteScript
in a specific use case. As @daggett pointed out, the cipher instance needed to be #init()
again before calling another #doFinal()
because G/CM cipher calculates and applies an authentication tag over the ciphertext.
这是相同行为的有效实现.
Here is a working implementation of the same behavior.
import org.apache.commons.codec.binary.Hex
import javax.crypto.Cipher
import javax.crypto.SecretKey
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec
import java.nio.charset.StandardCharsets
import java.security.SecureRandom
FlowFile flowFile = session.get()
if (!flowFile) {
return
}
try {
// Get the raw values of the attributes
String normalAttribute = flowFile.getAttribute('normal_attr')
String sensitiveAttribute = flowFile.getAttribute('sensitive_attr')
// Instantiate an encryption cipher
// Lots of additional code could go here to generate a random key, derive a key from a password, read from a file or keyring, etc.
String keyHex = "0123456789ABCDEFFEDCBA9876543210" // * 2 for 256-bit encryption
SecretKey key = new SecretKeySpec(Hex.decodeHex(keyHex), "AES")
byte[] ivBytes = new byte[16]
SecureRandom secureRandom = new SecureRandom()
secureRandom.nextBytes(ivBytes)
IvParameterSpec iv = new IvParameterSpec(ivBytes)
Cipher aesGcmEncCipher = Cipher.getInstance("AES/GCM/NoPadding", "BC")
aesGcmEncCipher.init(Cipher.ENCRYPT_MODE, key, iv)
String cipherTextBase64 = Base64.encoder.encodeToString(aesGcmEncCipher.doFinal(normalAttribute.bytes))
String encryptedNormalAttribute = "${Base64.encoder.encodeToString(ivBytes)}||${cipherTextBase64}"
// Re-initialize the cipher
secureRandom.nextBytes(ivBytes)
iv = new IvParameterSpec(ivBytes)
aesGcmEncCipher.init(Cipher.ENCRYPT_MODE, key, iv)
cipherTextBase64 = Base64.encoder.encodeToString(aesGcmEncCipher.doFinal(sensitiveAttribute.bytes))
String encryptedSensitiveAttribute = "${Base64.encoder.encodeToString(ivBytes)}||${cipherTextBase64}"
// Add a new attribute with the encrypted normal attribute
flowFile = session.putAttribute(flowFile, 'normal_attr_encrypted', encryptedNormalAttribute)
// Replace the sensitive attribute inline with the cipher text
flowFile = session.putAttribute(flowFile, 'sensitive_attr', encryptedSensitiveAttribute)
session.transfer(flowFile, REL_SUCCESS)
} catch (Exception e) {
log.error("There was an error encrypting the attributes: ${e.getMessage()}")
session.transfer(flowFile, REL_FAILURE)
}
每个加密操作的 IV (nonce) 是唯一且随机的,并且是 Base64 编码的,并使用 ||
作为分隔符添加到密文中.
The IV (nonce) is unique and random for each encryption operation, and is Base64-encoded and prepended to the ciphertext using ||
as a delimiter.
示例输出:
--------------------------------------------------
Standard FlowFile Attributes
Key: 'entryDate'
Value: 'Fri May 25 12:50:29 PDT 2018'
Key: 'lineageStartDate'
Value: 'Fri May 25 12:50:29 PDT 2018'
Key: 'fileSize'
Value: '29'
FlowFile Attribute Map Content
Key: 'normal_attr_encrypted'
Value: 'LOdE0y0LTZ4N/sax/sQnGw==||1c6V7b6F2yWxLPGWW4EOZcEYd8n9P6lMM4lPApTYQmI2/DCcMGyesn3WPA=='
Key: 'sensitive_attr'
Value: 'ZaA4Se5gck8Dgk7DeuYvYg==||pO4Oqt3FL/nvQDwJguCrJlwE5ORNIPwZlNEwzyFt5AVPRwZe+jpkJt0jGmAbmAY='
Key: 'filename'
Value: '246287463224762'
Key: 'normal_attr'
Value: 'This is a normal attribute.'
Key: 'path'
Value: './'
Key: 'uuid'
Value: 'cefae690-eeb2-4b82-8abd-e1b12fd6c410'
--------------------------------------------------
This is a plaintext message.
请注意,您的ExecuteScript
模块目录中将需要commons-codec-1.11.jar
.
Note that you will need commons-codec-1.11.jar
in your ExecuteScript
Module Directory.
这篇关于NiFi执行脚本加密json的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!