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

AES-256解密报错:wrong final block length问题修复咨询

修复AES-256-CBC解密时的"wrong final block length"错误

问题场景

向数据库插入100个密码经AES-256加密的用户后,解密时触发错误:
Error decrypting passwords error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length

原加密代码

const secretKey = crypto.randomBytes(32);
const secretIV = crypto.randomBytes(16);
const insertEncryptAESUsers = async() => {
    try {
        const client = await pool.connect();
        await client.query(`TRUNCATE users_aes RESTART IDENTITY`);
        const insertUserQuery = 'INSERT INTO users_aes (username, password) VALUES ($1, $2)';

        for (let i = 0; i < 100; i++) {
            const username = faker.internet.userName();
            const password = faker.internet.password();
            const cipher = crypto.createCipheriv('aes-256-cbc', secretKey, secretIV);
            let encryptedPassword = cipher.update(password, 'utf8', 'binary');
            encryptedPassword += cipher.final('binary');
            encryptedPassword = Buffer.from(encryptedPassword, 'binary').toString('base64');

            await client.query(insertUserQuery, [username, encryptedPassword]);

        }
        console.log('Users AES table filled successfully');
    } catch (err) {
        console.error('Error filling users AES table', err.message);
    }
}

原解密代码

const getUsersDecryptPasswordAES = async data => {
    try {
        const client = await pool.connect();
        const selectUsersQuery = 'SELECT username, password FROM users_aes';

        const queryResult = await client.query(selectUsersQuery);
        const passwords = queryResult.rows.map(row => row.password);


        for (let i = 0; i < passwords.length; i++) {
            const encryptedPassword = passwords[i];
            const decipher = crypto.createDecipheriv('aes-256-cbc', secretKey, Buffer.from(secretIV, 'base64'));
            let decryptedPassword = decipher.update(Buffer.from(encryptedPassword, 'base64'), 'binary', 'utf8');
            decryptedPassword += decipher.final('utf8');

            console.log(`User ${queryResult.rows[i].username} has password: ${decryptedPassword}`);
        }

        console.log('Password decryption successful');
    } catch (err) {
        console.error('Error decrypting passwords', err.message);
    }
}

错误原因

  1. IV处理错误:加密时secretIV是crypto.randomBytes(16)生成的原始二进制Buffer,解密时却错误地用Buffer.from(secretIV, 'base64')尝试解码,导致IV数据完全错误,解密流程无法匹配加密时的块对齐规则。
  2. update参数格式错误:解密时不需要将base64解码后的Buffer转成binary格式传递,直接传入Buffer即可,格式不匹配会导致解密数据截断或损坏。

修复后的解密代码

const getUsersDecryptPasswordAES = async data => {
    try {
        const client = await pool.connect();
        const selectUsersQuery = 'SELECT username, password FROM users_aes';

        const queryResult = await client.query(selectUsersQuery);

        for (let i = 0; i < queryResult.rows.length; i++) {
            const { username, password: encryptedPassword } = queryResult.rows[i];
            // 直接使用原始secretIV,无需base64解码
            const decipher = crypto.createDecipheriv('aes-256-cbc', secretKey, secretIV);
            // 直接传入base64解码后的Buffer,不需要转binary
            let decryptedPassword = decipher.update(Buffer.from(encryptedPassword, 'base64'), 'utf8');
            decryptedPassword += decipher.final('utf8');

            console.log(`User ${username} has password: ${decryptedPassword}`);
        }

        console.log('Password decryption successful');
    } catch (err) {
        console.error('Error decrypting passwords', err.message);
    }
}

额外注意事项

  • secretKey和secretIV必须持久化存储(比如写入配置文件或环境变量),不能每次服务重启都重新生成,否则之前加密的所有数据都无法解密。
  • 加密时的输出格式可以简化:直接使用cipher.update和cipher.final的base64输出,无需先转binary再转base64,优化后的加密代码片段如下:
    // 加密部分简化
    const cipher = crypto.createCipheriv('aes-256-cbc', secretKey, secretIV);
    let encryptedPassword = cipher.update(password, 'utf8', 'base64');
    encryptedPassword += cipher.final('base64');
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 06:43:08