解密ES中的logstash加密数据时遇到问题

时间:2019-06-13 10:00:20

标签: java elasticsearch encryption logstash logstash-filter

我正在使用logstash密码过滤器加密一些数据,并将加密的数据存储在elasticsearch中。用于加密的代码段如下:

filter {
cipher {
algorithm => "aes-256-cbc"
cipher_padding => 1
iv_random_length => 16
key => "<32_DIGITS_KEY>"
key_size => 32
mode => "encrypt"
source => "[message]"
target => "[message_enc]"
}
}

当我使用Java代码从Elasticsearch索引中读取数据并解密时,我在实际数据之前得到了相同的随机unicode字符串。示例随机字符串为“r��1�> <

我没有在代码中找到任何解决此问题的方法。

请帮助我解决这个问题。

@ gusto2

用于解密数据的Java代码如下:

private static final String secretKey = "<32_DIGITS_KEY(SAME-AS-USED-IN-ENCRYPTION)>";
static String encrypt ;
//@PostConstruct
public static String encrypt(String strToEncrypt , byte[] salt)
{
    try
    {
        IvParameterSpec ivspec = new IvParameterSpec(salt);

        SecretKeySpec speckKey = new SecretKeySpec(secretKey.getBytes("UTF-8"), "AES");

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, speckKey , ivspec);
        byte[] encrypted = cipher.doFinal(strToEncrypt.getBytes());
        return Base64.encodeBase64String(encrypted);
    }
    catch (Exception e)
    {
        System.out.println("Error while encrypting: " + e.toString());
    }
    return null;
}

public static String decrypt(String encrypted ,byte[] salt) {
    try {
        IvParameterSpec ivspec = new IvParameterSpec(salt);

        SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes("UTF-8"), "AES");

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        cipher.init(Cipher.DECRYPT_MODE, keySpec , ivspec);
        //return new String(cipher.doFinal(Base64.getDecoder().decode(encrypted)));
        byte[] original =  cipher.doFinal(Base64.decodeBase64(encrypted));

        return new String(original);
    } catch (Exception ex) {
                    ex.printStackTrace();
    }

    return null;
}

public  static void main (String args[]){
    byte[] IV = new byte[16];
    SecureRandom random = new SecureRandom();
    random.nextBytes(IV);
    final byte[] salt = IV;
    String strToEncrypt = "533032715323";
    encrypt = encrypt(strToEncrypt , salt);
    //encrypt = "w7oA8EdWmFNfBSUX1ZM0ixYU1Zep6tOnqz8b81X24n8=";
    System.out.println(encrypt);
    String decrpytStr = decrypt(encrypt , salt);
    System.out.println(decrpytStr);
    System.out.println(decrpytStr.equalsIgnoreCase(strToEncrypt));
}

1 个答案:

答案 0 :(得分:1)

  

我在获得实际数据之前得到了相同的随机unicode字符串

看看cipher filter的工作方式,输出的格式为Base64( iv + plaintext)

  

盐的长度与“ iv_random_length”的值-16和盐(如果16大小的随机字符串)相同。

使用CBC模式,在IV不正确时会产生效果。

注释中的问题旨在让您了解要解密的内容。解密时,盐不是随机的。在这种情况下,它是密文的前16个字节。因此,您应该使用前16个字节,将它们用作IV并解密其余字节。

   byte[] decodedCiphertext = Base64.getDecoder().decode(encrypted);
   IvParameterSpec ivspec = new IvParameterSpec(decodedCiphertext, 0, 16);
   ...
   byte[] original =  cipher.doFinal(decodedCiphertext, 16, decodedCiphertext.length);