You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Logstash管道中AES加密Ruby代码故障排查求助

Logstash Ruby AES-GCM加密代码修复

我有一段实现AES加密的Java代码,逻辑是用PBKDF2生成密钥,AES-GCM模式加密,最后把IV、Salt和加密数据(含GCM标签)拼接后Base64编码:

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(secretKey.toCharArray(), salt.getBytes(), 65536, 256);
SecretKey secret = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), "AES");

if (data == null)
    return encryptedText;

Cipher encryptCipher = Cipher.getInstance("AES/GCM/NoPadding");

// get IV
byte[] iv = getRandomNonce(12);
encryptCipher.init(Cipher.ENCRYPT_MODE, secret, new GCMParameterSpec(128, iv));
// encrypted data:
byte[] encryptedBytes = encryptCipher.doFinal(data.getBytes("UTF-8"));

// prefix IV and Salt to cipher text
byte[] cipherTextWithIvSalt = ByteBuffer.allocate(iv.length + salt.length() + encryptedBytes.length).put(iv)
        .put(salt.getBytes()).put(encryptedBytes).array();

encryptedText = Base64.getEncoder().encodeToString(cipherTextWithIvSalt);

现在我在Logstash管道里用Ruby代码尝试实现相同逻辑,但无法正常工作,代码如下:

ruby {
code => "
  require 'openssl'
  require 'base64'

  password = 'secret_key'
  salt = 'random_salt'
  iterations = 65536
  key_len = OpenSSL::Cipher.new('aes-256-gcm').key_len
  key = OpenSSL::PKCS5.pbkdf2_hmac(password, salt, iterations, key_len, 'sha256')

  cipher = OpenSSL::Cipher.new('aes-256-gcm')
  cipher.encrypt
  cipher.key = key
  iv = Random.new.bytes(12)
  encrypted = cipher.update(event.get('secret')) + cipher.final
  length=iv.length+salt.length+encrypted.length
  
    // buffer =IO::Buffer.new(10)// not working
    
    
  encrypted_text = Base64.encode64(buffer).strip

  event.set('message_encrypted', encrypted_text)
"
add_field => {
      "new_secret" => "%{[message_encrypted]}"
    }
}

代码问题分析

你的Ruby代码存在以下关键问题:

  • 未定义buffer变量:直接使用未初始化的buffer导致报错,且未正确拼接IV、Salt和加密数据
  • 遗漏GCM认证标签:AES-GCM模式下,Ruby的OpenSSL实现不会自动把认证标签附加到加密数据后,需要手动获取cipher.tag并拼接
  • 语法错误:Ruby注释使用#而非//,原始代码中的// buffer =IO::Buffer.new(10)是无效语法
  • 编码不一致:未指定明文转字节的编码,可能和Java的UTF-8编码产生差异
  • 未设置IV到加密器:生成IV后没有绑定到cipher实例,加密逻辑不完整

修复后的Ruby代码

ruby {
  code => "
    require 'openssl'
    require 'base64'

    password = 'secret_key'
    salt = 'random_salt'
    iterations = 65536
    
    cipher = OpenSSL::Cipher.new('aes-256-gcm')
    cipher.encrypt
    key_len = cipher.key_len
    key = OpenSSL::PKCS5.pbkdf2_hmac(password, salt, iterations, key_len, 'sha256')

    cipher.key = key
    iv = Random.new.bytes(12)
    cipher.iv = iv # 将IV绑定到加密器实例

    # 处理空值,对应Java的data==null逻辑
    plaintext = event.get('secret')
    return unless plaintext

    # 统一使用UTF-8编码转字节,和Java保持一致
    encrypted_data = cipher.update(plaintext.encode('UTF-8')) + cipher.final
    gcm_tag = cipher.tag # 获取GCM认证标签

    # 拼接IV、Salt字节、加密数据、GCM标签
    cipher_text_with_iv_salt = iv + salt.bytes.pack('C*') + encrypted_data + gcm_tag

    # 使用strict_encode64避免添加换行符,和Java的Base64.getEncoder()输出一致
    encrypted_text = Base64.strict_encode64(cipher_text_with_iv_salt)

    event.set('message_encrypted', encrypted_text)
  "
  add_field => {
    "new_secret" => "%{[message_encrypted]}"
  }
}

修复说明

  1. 新增cipher.iv = iv:将生成的IV绑定到加密器,确保加密逻辑正确
  2. 空值处理:添加return unless plaintext,对应Java中data == null的判断
  3. 统一编码:使用plaintext.encode('UTF-8')确保明文转字节和Java一致
  4. 正确拼接数据:按IV → Salt字节 → 加密数据 → GCM标签的顺序拼接,和Java逻辑对齐
  5. 使用Base64.strict_encode64:避免默认encode64添加换行符,保证输出格式和Java一致

内容的提问来源于stack exchange,提问作者Manoj Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 07:45:55