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

Java转Ruby的AES加密代码输出不一致,求Ruby代码修正方案

AES加密Java转Ruby输出不一致的修复方案

用户尝试将Java AES加密代码转换为Ruby实现,但两者加密输出始终不一致。以下是双方代码核心逻辑梳理、Ruby代码错误点及修正方案:

Java代码核心逻辑梳理

Java代码的关键加密规则如下:

// 密钥生成:将原始密钥转为UTF-8字节数组,经Base64编码后再解码得到密钥字节
public static SecretKey secretKeyGeneration(String requestor, String key, String algo, Integer size) {
    NAPISecretKey napiSecretKey = new NAPISecretKey();
    napiSecretKey.setAlgorithm(algo);
    napiSecretKey.setKey(StringUtil.fromByteArrayToBase64((key).getBytes()));
    napiSecretKey.setSize(size);
    return decodeSecretKey(napiSecretKey.getKey(), napiSecretKey.getAlgorithm());
}

// 加密规则:AES/CBC/PKCS5Padding模式,使用全0的16字节IV
public static byte[] encrypt(SecretKey secretKey, byte[] plaintext) throws Exception {
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(new byte[16]));
    return cipher.doFinal(plaintext);
}

Ruby代码的错误点及修正

错误1:密钥生成逻辑完全偏离

Ruby中错误地将密钥的每个字节数值拼接成字符串再做Base64编码,而Java是直接对密钥的UTF-8字节数组进行Base64编码。

错误2:加密模式不匹配

Java使用AES/CBC/PKCS5Padding模式,Ruby却误用了AES-256-ECB模式(ECB不支持IV,且加密逻辑与CBC完全不同)。

错误3:明文处理冗余且错误

Ruby中多余地将明文的字节数值拼接成字符串,Java是直接使用明文的UTF-8字节数组进行加密。

错误4:IV设置无效

ECB模式下设置IV无意义,切换到CBC模式后需正确设置全0的16字节IV。

修正后的Ruby代码

def encrypt_data
  encryption_key = "12345678"
  requestor_id = "IN000000"
  encrypted_data = params[:orderReqDtls] || request.headers[:orderReqDtls]
  encrypted_data = @order_data if caller_locations.any? { |loc| loc.label == 'generate_json_order_data' }
  
  secret_key = secret_key_generation(requestor_id, encryption_key, "AES", 256)
  encrypted_string = encrypt(secret_key, encrypted_data)
  encrypted_data = Base64.strict_encode64(encrypted_string)
  
  render json: { data: encrypted_data }
end

def secret_key_generation(requestor, key, algo, size)
  napi_secret_key = NAPISecretKey.new
  napi_secret_key.algorithm = algo
  # 修正:直接对密钥的UTF-8字节数组做Base64编码,与Java逻辑对齐
  base64_encoded_key = Base64.strict_encode64(key.encode('UTF-8'))
  napi_secret_key.key = base64_encoded_key
  napi_secret_key.size = size
  
  decode_secret_key(napi_secret_key.key, napi_secret_key.algorithm)
end

def decode_secret_key(key, algo)
  if algo == "AES"
    # 解码Base64得到原始密钥字节数组
    Base64.decode64(key)
  else
    raise "#{algo} is not supported"
  end
end

def encrypt(secret_key, plaintext)
  # 修正:使用CBC模式,对应Java的AES/CBC/PKCS5Padding
  cipher = OpenSSL::Cipher.new('AES-256-CBC')
  cipher.encrypt
  # 设置密钥
  cipher.key = secret_key
  # 修正:设置全0的16字节IV,与Java一致
  cipher.iv = "\x00" * 16
  # 修正:直接使用明文的UTF-8字节,无需额外处理
  encrypted_data = cipher.update(plaintext.encode('UTF-8')) + cipher.final
end

额外注意事项

  • AES-256要求密钥长度为32字节(256位),若你的encryption_key长度不足,Java会抛出InvalidKeyException,请确保密钥符合长度要求。
  • 确认Ruby和Java使用的Base64编码标准一致(均为标准Base64,无URL安全或换行差异)。

内容的提问来源于stack exchange,提问作者shaik praveen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 07:22:53