You need to enable JavaScript to run this app. Android Kotlin实现CryptoJS.AES加密结果与JS端不一致问题咨询
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin实现CryptoJS.AES加密结果与JS端不一致问题咨询

问题根因排查

核心错误点

  • 字节转换逻辑完全不匹配
    JS端所有输入(密钥、IV、明文)都是直接将原始字符串转为UTF-8编码的原始字节参与加密,而Kotlin端额外做了一次字节转十六进制字符串的操作,再把十六进制字符串的字符转为字节输入,相当于输入内容和JS端完全不一致。例如原始字节为0x9f,转十六进制字符串得到"9f",再转字节就是0x39、0x66两个完全不同的字节,加密结果必然不同。
  • 密钥截取逻辑错误
    JS端配置keySize:16对应AES-128,要求密钥是16字节原始UTF-8字节。Kotlin端先把原始密钥转成两倍长度的十六进制字符串,再截取前16字节,实际参与加密的密钥和JS端完全不匹配。
  • IV生成逻辑错误
    JS端IV是取UTC ISO时间前16位字符的UTF-8编码(固定16字节),Kotlin端先把时间字节转十六进制字符串再取前16字节,IV内容和JS端完全不一致。

修复后的Kotlin实现代码

// 直接取原始密钥的UTF-8字节,不要转十六进制
val keyBytes = getSecretKey().toByteArray(Charsets.UTF_8)
// 生成和JS逻辑完全一致的IV:UTC ISO时间前16位的UTF-8字节
val piv = Instant.now().toString().substring(0, 16)
val ivBytes = piv.toByteArray(Charsets.UTF_8)
// 明文和JS逻辑对齐:piv拼接用户凭证后的UTF-8字节
val msgBytes = (piv + userCredentials).toByteArray(Charsets.UTF_8)

// 初始化Cipher,部分Android低版本PKCS7Padding可替换为PKCS5Padding,二者对AES兼容
val cipher = Cipher.getInstance("AES/CBC/PKCS7Padding")
val keySpec = SecretKeySpec(keyBytes, 0, 16, "AES")
val ivParameterSpec = IvParameterSpec(ivBytes)
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivParameterSpec)

val encryptResult = cipher.doFinal(msgBytes)
// 输出Base64格式和CryptoJS.encrypt的默认输出格式完全匹配
return Base64.getEncoder().encodeToString(encryptResult)

额外校验点

  • 确认JS端getSecretKey()返回的字符串长度至少16位,密钥截取规则两端完全对齐
  • 确认两端UTC时间生成逻辑无时区、毫秒级差异,避免IV内容不一致
  • 确认JS端最终输出的是encrypted.toString(),和Kotlin端输出的Base64格式匹配

内容的提问来源于stack exchange,提问作者Ahmad Shahwaiz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 04:48:02