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)パディングをfalseに設定し、ECBとCBCは完全なブロックでのみ動作します。これが、ブロックサイズの倍数ではないものにパディングが必要な理由です。行を削除するか (推奨)、独自のパディングを作成する必要があります (独自の暗号を発明するという罠に陥ります)。

ECB と CBC はどちらも、プレーンテキスト/パディング Oracle 攻撃に対して本質的に脆弱であることに注意してください。とにかく ECB は安全ではなく、IV を使用しません。トランスポート モードのセキュリティには、MAC が必要であるか、認証された暗号を使用する必要があります。トランスポート セキュリティを実現するのは難しいため、DTLS を試してください。

于 2019-02-27T15:26:31.227 に答える