2

我一直在尝试使用 NodeJS 中的“crypto”库加密一些消息,但出现以下错误:

(节点:31732)UnhandledPromiseRejectionWarning:错误:错误:0607F08A:数字信封例程:EVP_EncryptFinal_ex:数据不是块长度的倍数

在 Cipheriv.final (internal/crypto/cipher.js:164:28)
在 self.test (...)

self.test = async function(info, object) {
    let message = {
        info: info,
        object: object
    };

    let iv = crypto.randomBytes(16)
    let key = Buffer.from(config.key, 'utf8');
    let cipher = crypto.createCipheriv("aes-128-ecb", key, '');
    cipher.setAutoPadding(false)
    let encrypted = cipher.update(JSON.stringify(message));
    encrypted = Buffer.concat([iv, encrypted, cipher.final()]);
    encrypted = encrypted.toString('base64');

    console.log(encrypted);
}

cipher.final()如上面的堆栈所示,该错误源自调用。

我无法弄清楚这个错误的含义以及如何解决它。不幸的是,由于限制(我正在尝试通过 UDP 发送加密数据),我无法使用像 CBC 这样的算法(消息的接收顺序与加密顺序不同)。

任何帮助是极大的赞赏!

4

1 回答 1

3

cipher.setAutoPadding(false)将 padding 设置为 false,ECB 和 CBC 仅在完整块上运行 - 这就是为什么任何不是块大小的倍数的东西都需要填充的原因。您应该删除该行(首选)或创建自己的填充(并陷入发明自己的加密的陷阱)。

请注意,ECB 和 CBC 天生就容易受到明文/填充预言机攻击。无论如何,欧洲央行是不安全的,它不使用 IV。对于传输模式的安全性,您需要一个 MAC,或者您应该使用经过身份验证的密码。传输安全很难实现,试试 DTLS。

于 2019-02-27T15:26:31.227 回答