NiFi执行脚本加密json [英] NiFi execute script encrypt json

查看:177
本文介绍了NiFi执行脚本加密json的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,指的是这个问题:



没有try catch:





基本上它会尝试执行以下脚本:

  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 {
//获取属性的原始值
String normalAttribute = flowFile.getAttribute( 'Normal Attribute')
S tring sensitiveAttribute ='flowFile.getAttribute'('Sensitive Attribute')

//实例化一个加密密码
//许多额外的代码可以在这里生成一个随机密钥,从一个密钥中派生一个密钥密码,从文件或密钥环中读取等
字符串keyHex =0123456789ABCDEFFEDCBA9876543210// * 2用于256位加密
SecretKey密钥=新SecretKeySpec(keyHex.getBytes(StandardCharsets.UTF_8), AES)
IvParameterSpec iv = new IvParameterSpec(keyHex [0 ..< 16] .getBytes(StandardCharsets.UTF_8))

密码aesGcmEncCipher = Cipher.getInstance(AES / GCM / NoPadding,BC)
aesGcmEncCipher.init(Cipher.ENCRYPT_MODE,key,iv)

字符串encryptedNormalAttribute = Base64.encoder.encodeToString(aesGcmEncCipher.doFinal(normalAttribute.bytes))
String encryptedSensitiveAttribute = Base64.encoder.encodeToString(aesGcmEncCipher.doFinal(sensitiveAttribute.bytes))

//使用enc添加一个新属性rypted normal属性
flowFile = session.putAttribute(flowFile,'Normal Attribute(encrypted)',encryptedNormalAttribute)

//用密文替换内联的敏感属性
flowFile = session.putAttribute(flowFile,'Sensitive Attribute',encryptedSensitiveAttribute)
session.transfer(flowFile,REL_SUCCESS)
} catch(Exception e){
log.error(属性:$ {e.getMessage()})
session.transfer(flowFile,REL_FAILURE)
}


解决方案

该脚本是作为一个未经测试的(和非工作的)模板提供的,以演示 ExecuteScript #doFinal()之前,密码实例必须再次为 #init()因为G / CM密码计算并在密文上应用认证标签。

以下是相同行为的工作实现。

  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
$ b FlowFile flowFile = session.get()
$ b $ if(!flowFile){
return
}

try {
//获取属性的原始值
String normalAttribute = flowFile.getAttribute('normal_attr')
String sensitiveAttribute = flowFile.getAttribute('sensitive_attr')

//实例化加密密码
//许多附加代码可以在这里生成一个随机密钥,从密码派生密钥,从文件或密钥环中读取等。
String keyHex =0123456789ABCDEFFEDCBA9876543210// * 2用于256位加密
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)

密码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-初始化密码


cipherTextBase64 = Base64.encoder.encodeToString(aesGcmEncCipher.doFinal(sensitiveAttribute.bytes))
String encryptedSensitiveAttribute =$ {Base64.encoder.encodeToString(ivBytes)} || $ {cipherTextBase64}

/ /添加一个新的属性与加密的普通属性
flowFile = session.putAttribute(flowFile,'normal_attr_encrypted',encryptedNormalAttribute)

//用密文替换内联敏感属性
flowFile = session .putAttribute(flowFile,'sensitive_attr',encryptedSensitiveAttribute)
session.transfer(flowFile,REL_SUCCESS)
} catch(Exception e){
log.error(加密属性时出错:$ {e.getMessage()})
session.transfer(flowFile,REL_FAILURE)
}

IV( nonce )对于每个加密操作都是唯一且随机的,并且使用 || 作为分隔符。



示例输出:

  -------- ------------------------------------------ 
标准FlowFile属性
Key:'entryDate'
Value:'Fri May 25 12:50:29 PDT 2018'
Key:'lineageStartDate'
Value:'Fri May 25 12:50:29 PDT 2018'
键:'fileSize'
值:'29'
FlowFile属性映射内容
键:'normal_attr_encrypted'
值:'LOdE0y0LTZ4N / sax / sQnGw == || 1c6V7b6F2yWxLPGWW4EOZcEYd8n9P6lMM4lPApTYQmI2 / DCcMGyesn3WPA ==
键: 'sensitive_attr'
值: 'ZaA4Se5gck8Dgk7DeuYvYg == || pO4Oqt3FL / nvQDwJguCrJlwE5ORNIPwZlNEwzyFt5AVPRwZe + jpkJt0jGmAbmAY ='
键: '文件名'
值:'246287463224762'
键:'normal_attr'
值:'这是一个正常的属性。'
键:'路径'
值:'./'
键:'uuid'
值:'cefae690-eeb2-4b82-8abd-e1b12fd6c410'
---------------------- --------------------- -------
这是一个明文信息。

请注意,您需要 commons-codec-1.11.jar 在你的 ExecuteScript 模块目录中。

Hi referring to this question: nifi encrypt json I have tried using the template provided. I found an error when it tries to execute the executeScript processor:

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)
}

解决方案

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)
}

The IV (nonce) is unique and random for each encryption operation, and is Base64-encoded and prepended to the ciphertext using || as a delimiter.

Example output:

--------------------------------------------------
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.

Note that you will need commons-codec-1.11.jar in your ExecuteScript Module Directory.

这篇关于NiFi执行脚本加密json的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆