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

Ruby的DES-EDE-CBC加密迁移至Java结果不一致如何解决?

问题修复方案

你当前加密结果不匹配是因为Ruby和Java两端的加密逻辑存在四处核心差异,逐一修复即可对齐结果:

核心差异点

  • 密钥处理逻辑不匹配:Ruby端key.split.pack("H*")是将key作为十六进制字符串解码为原始字节数组,Java端直接调用key.getBytes()是按UTF-8编码转字节,两者生成的密钥完全不同。
  • IV未显式对齐:Ruby的OpenSSL::Cipher在CBC模式下默认会生成随机IV,Java端固定使用全0 IV,必须两端显式设置相同IV才能对齐结果。
  • Padding规则不匹配:Ruby的OpenSSL::Cipher默认开启PKCS5Padding,Java端使用NoPadding,即使输入刚好为8字节的块大小,Ruby默认会追加8字节的填充位,加密结果长度和内容都会不一致。
  • 加密方法调用不规范:Java端仅调用cipher.update()只会返回部分加密结果,Ruby端也未调用cipher.final补全输出,必须调用收尾方法获取完整的加密输出。

修正后的Ruby代码(对齐参数,避免默认值差异)

open_ssl_cipher = OpenSSL::Cipher.new("DES-EDE-CBC");
input = "abcdefgh";
key = "mytyyrxfmtmtmt23mtmtmqpmpm45t45"

hex_input = input.unpack("H*").join.upcase
cipher = open_ssl_cipher.encrypt
cipher.padding = 0 # 关闭填充,和Java NoPadding对齐
cipher.iv = "\0" * 8 # 显式设置全0 IV,和Java对齐
cipher.key = [key].pack("H*") # 统一密钥解码逻辑
s = cipher.update([hex_input].pack("H*")) + cipher.final
input_enc = s.unpack1("H*").upcase

修正后的Java代码

import org.bouncycastle.util.encoders.Hex;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.nio.charset.StandardCharsets;
import java.security.Key;

public class EncService {

  private static final String TRANSFORMATION = "DESede/CBC/NoPadding";
  private static final String ALGORITHM = "DESede";

  public static void main(String[] args) {
    EncService service = new EncService();
    service.encrypt();
  }

  public String encrypt() {
    String data = "abcdefgh";
    String key = "mytyyrxfmtmtmt23mtmtmqpmpm45t45";
    try {
      Cipher cipher = Cipher.getInstance(TRANSFORMATION);
      IvParameterSpec ivParameterSpec = new IvParameterSpec(new byte[8]);
      // 修复密钥解码逻辑,和Ruby pack("H*")结果对齐
      DESedeKeySpec spec = new DESedeKeySpec(Hex.decode(key));
      Key secretKey = SecretKeyFactory.getInstance(ALGORITHM).generateSecret(spec);
      cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
      // 调用doFinal获取完整加密结果
      byte[] bytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
      String s = Hex.toHexString(bytes).toUpperCase();
      System.out.printf("output: %s%n", s);
      return s;

    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
}

内容的提问来源于stack exchange,提问作者Nagendra Prasadu Gandla

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 22:15:03