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

Java加密字符串在Angular中无法解密的问题及Angular端修正方案咨询

解决Java AES加密后Angular无法解密的问题

我仔细对比了你的Java和Angular代码,找到几个关键的不匹配点,这些就是导致解密失败的核心原因。下面是问题分析和修改后的Angular代码:

关键问题梳理

  • PBKDF2密钥长度参数错误:Java生成的是256位(32字节)的AES密钥,但CryptoJS的keySize参数是按4字节的word计算的,256位对应8个word。你之前写的keySize:256会生成1024位的密钥,完全不符合要求。
  • IV处理不一致:Java中IV是将字符串"79994A6EF73DA76C"直接转成UTF-8字节,而你的Angular代码混合使用了Hex.parse和Utf8.parse,导致IV字节序列和Java端不匹配。
  • 密文解析错误:Java加密后输出的是Base64编码的密文,CryptoJS解密时需要正确解析这个Base64字符串,而不是直接传入原始字符串。
  • 冗余编码方法:你的encoder和toWordArray方法存在冗余,CryptoJS本身的编码工具已经足够完成这些操作。

修改后的Angular代码

export class PrepaidCryptoService {
  private readonly KEY_IV = "79994A6EF73DA76C";
  private readonly PASSWORD = "EF737CC29DAE7C80644A5B01544CBA61";
  private readonly SALT = "12345";

  constructor() { }

  encrypt(value: string): string {
    // 生成与Java一致的256位密钥(8个word,每个word4字节)
    const key = CryptoJS.PBKDF2(this.PASSWORD, this.SALT, { 
      keySize: 8, 
      iterations: 65536,
      hasher: CryptoJS.algo.SHA1 // 显式指定SHA1,匹配Java的PBKDF2WithHmacSHA1
    });
    // IV与Java逻辑一致:字符串转UTF-8字节
    const iv = CryptoJS.enc.Utf8.parse(this.KEY_IV);
    // 加密:明文转UTF-8,使用CBC模式和PKCS7填充(与Java的PKCS5Padding等价)
    const encrypted = CryptoJS.AES.encrypt(
      CryptoJS.enc.Utf8.parse(value), 
      key, 
      { iv: iv, padding: CryptoJS.pad.Pkcs7, mode: CryptoJS.mode.CBC }
    );
    // 返回Base64编码的密文,和Java输出格式匹配
    return encrypted.ciphertext.toString(CryptoJS.enc.Base64);
  }

  decrypt(value: string): string {
    // 生成与加密时一致的密钥
    const key = CryptoJS.PBKDF2(this.PASSWORD, this.SALT, { 
      keySize: 8, 
      iterations: 65536,
      hasher: CryptoJS.algo.SHA1
    });
    // IV保持与Java一致
    const iv = CryptoJS.enc.Utf8.parse(this.KEY_IV);
    // 解密:先将Base64密文转成CryptoJS可识别的WordArray
    const decrypted = CryptoJS.AES.decrypt(
      { ciphertext: CryptoJS.enc.Base64.parse(value) }, 
      key, 
      { iv: iv, padding: CryptoJS.pad.Pkcs7, mode: CryptoJS.mode.CBC }
    );
    // 将解密后的字节转成UTF-8字符串
    return decrypted.toString(CryptoJS.enc.Utf8);
  }
}

额外说明

  • PKCS5与PKCS7填充的关系:Java中的PKCS5Padding和CryptoJS的Pkcs7是等价的。因为PKCS5原本只针对8字节块大小,而AES是16字节块,Java会自动使用PKCS7的填充逻辑,所以这里不需要做额外调整。
  • 显式指定哈希算法:虽然CryptoJS的PBKDF2默认使用SHA1,但显式指定hasher: CryptoJS.algo.SHA1可以避免未来版本默认值变化的风险,确保和Java端完全匹配。
  • 代码规范优化:把常量改成private readonly更符合TypeScript的最佳实践,避免意外修改核心配置。

现在用这个修改后的代码测试,应该就能正常解密Java加密的消息了。

内容的提问来源于stack exchange,提问作者Pratiksha Magar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 20:37:47