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

Node.js解密Android端AES加密字符串时遇最终块长度错误

解决Node.js解密Android AES加密文本时的"wrong final block length"错误

问题根源

你遇到的错误本质是两个关键问题导致的:

1. AES算法版本不匹配

Android的SecretKeySpec会根据密钥的字节长度自动适配AES版本:

  • 16字节密钥 → AES-128
  • 24字节密钥 → AES-192
  • 32字节密钥 → AES-256

但你的Node.js代码直接写死了aes-256-cbc,如果Android实际用的是其他版本(比如AES-128),解密过程就会完全错乱。

2. decipher.update的参数错误

你已经把加密字符串转成了Base64解码后的Buffer:

var messageToDecrypt = Buffer.from(encryptedMessage, "base64");

但调用update时还传了'base64'作为输入编码,这会让Node.js重复解码已经是原始字节的Buffer,直接破坏了加密数据的块结构,最终触发块长度错误。

修正后的代码

const crypto = require('crypto');

function decryptAndroidAes(encryptedMessage) {
    // 解码Base64为原始加密字节
    const cipherBuffer = Buffer.from(encryptedMessage, "base64");
    // 密钥、IV必须和Android端完全一致(编码、内容都要匹配)
    const key = Buffer.from("MY_KEY", "utf8");
    const iv = Buffer.from("MY_IV", "utf8");

    // 根据密钥长度自动匹配AES版本
    let algorithm;
    switch (key.length) {
        case 16:
            algorithm = 'aes-128-cbc';
            break;
        case 24:
            algorithm = 'aes-192-cbc';
            break;
        case 32:
            algorithm = 'aes-256-cbc';
            break;
        default:
            throw new Error('密钥长度不符合AES规范,必须是16/24/32字节');
    }

    const decipher = crypto.createDecipheriv(algorithm, key, iv);
    // 直接传入Buffer,不需要指定输入编码,输出设为utf8
    let plaintext = decipher.update(cipherBuffer, undefined, 'utf8');
    // 完成解密拼接
    plaintext += decipher.final('utf8');
    return plaintext.trim();
}

额外注意点

  • 确认MY_IV的长度是16字节(AES的块大小),Android端的IvParameterSpec要求IV必须和块大小一致,所以你的MY_IV应该是16个UTF-8字符。
  • 确保Android端的toBase64是标准Base64编码(无多余换行、符合RFC 4648),避免解码时出现数据损坏。
  • 密钥长度必须严格是16/24/32字节,否则Android端初始化Cipher时也会报错,所以你的MY_KEY要符合这个要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 09:52:46