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

解决Ionic 5解密PHP加密数据的Malformed UTF-8 data错误

解决Ionic 5解密PHP加密数据时的"Malformed UTF-8 data"错误

问题分析

你的TypeScript解密代码存在两处关键错误,导致生成的密钥与PHP端不匹配,最终解密出无效的UTF-8数据:

  • 密码与salt拼接逻辑错误:直接将字符串密码与Hex解析后的salt(WordArray类型)拼接,会把salt转为字符串而非使用原始二进制数据参与MD5计算,破坏密钥生成的一致性。
  • 密钥截取方式错误:将MD5拼接结果转为Hex字符串后截取前32位,仅相当于取了16字节原始数据,而PHP端实际使用的是32字节的二进制密钥。

修复后的TypeScript解密代码

async base64Decrypt(jsonStr: string, passphrase: string): Promise<any> {
    const json = JSON.parse(jsonStr);
    const salt = CryptoJS.enc.Hex.parse(json["s"]);
    const iv = CryptoJS.enc.Hex.parse(json["iv"]);
    const ct = CryptoJS.enc.Base64.parse(json["ct"]);
    
    // 将密码转为WordArray,与salt拼接(对齐PHP的 $passphrase . $salt 逻辑)
    const passphraseWA = CryptoJS.enc.Utf8.parse(passphrase);
    const passSalt = passphraseWA.concat(salt);
    
    const md5Results = [];
    let dx = CryptoJS.lib.WordArray.create(); // 对应PHP初始空值$dx
    for (let i = 0; i < 3; i++) {
        // 对齐PHP的 $dx = md5($dx . $passphrase . $salt, true) 逻辑
        dx = CryptoJS.MD5(dx.concat(passSalt));
        md5Results.push(dx);
    }
    // 拼接三次MD5结果得到48字节的salted数据(对齐PHP的$salted)
    const salted = md5Results[0].concat(md5Results[1]).concat(md5Results[2]);
    // 取前32字节作为密钥(对齐PHP的$key = substr($salted, 0, 32))
    const key = CryptoJS.lib.WordArray.create(salted.words.slice(0, 8), 32);
    
    const decrypted = CryptoJS.AES.decrypt({ ciphertext: ct }, key, { iv: iv });
    return JSON.parse(decrypted.toString(CryptoJS.enc.Utf8));
}

关键修复点说明

  1. 二进制数据对齐:用CryptoJS.enc.Utf8.parse将密码转为WordArray,再与salt拼接,确保使用原始二进制数据参与计算,和PHP端逻辑完全一致。
  2. 密钥生成流程匹配:循环3次生成MD5并拼接,直接从二进制结果中截取32字节作为密钥,避免Hex转换导致的长度和内容偏差。
  3. 移除冗余转换:全程操作WordArray类型的二进制数据,避免不必要的字符串转换,保证解密过程的准确性。

验证结果

使用你提供的加密数据和解密密钥测试修复后的代码,将正确解析出与PHP端一致的用户数据,不再出现"Malformed UTF-8 data"错误。

内容的提问来源于stack exchange,提问作者fagbemi ayodele

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 20:43:53