bugfix> groovy > 投稿

こんにちはこの質問を参照してください: Nifi暗号化JSON 私は使用してみましたテンプレート 提供されます。 executeScriptプロセッサを実行しようとするとエラーが見つかりました。

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

回答 1 件
  • このスクリプトは、 ExecuteScript の機能を実証するために、テストされていない(および機能しない)テンプレートとして提供されました。  特定のユースケースで。 @daggettが指摘したように、暗号インスタンスは #init() である必要がありました  別の #doFinal() を呼び出す前に再び  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
    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(一回だけ)は暗号化操作ごとに一意でランダムであり、base64エンコードされ、 || を使用して暗号文の先頭に追加  区切り文字として。

    出力例:

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

    commons-codec-1.11.jar が必要になることに注意してください  あなたの ExecuteScript で  モジュールディレクトリ

あなたの答え