node.js - エラー:06065064:デジタル エンベロープ ルーチン:EVP_DecryptFinal_ex:不正な復号化

okwaves2024-01-25  9

お願いします。暗号化されたデータをデータベースに保存し、復号化されたデータをフロントエンドで表示しようとしています。 暗号化は正常に機能しますが、復号化しようとすると、次のエラーが表示されます。 error:06065064:digital封筒ルーチン:EVP_DecryptFinal_ex:bad decrypt

これが私のコードです:

const express = require('express');
const router = express.Router();
const { check, validationResult } = require('express-validator');
const User = require('../models/Users');
const Message = require('../models/Messages');
const auth = require('../middleware/auth');
const AES = require('../config/aes-encryption');

// @route GET api/messages
// @desc get all messages
// @access private 
    router.get('/', auth, async(req, res) => {
    try {

        const messages = await Message.find();

        messages.forEach((msg) => {
            console.log(msg.text);
            
    // Here is where i have the error
            AES.decrypt(msg.text);
        });
        
        res.json(messages);
        

        
    } catch (error) {
        console.error(error.message);
        res.status(500).json({ msg: "Internal Sever Error" }); 
    }
});

// @route POST api/messages
// @desc add messages
// @access private 

router.post('/', [auth, [check('text', 'Please enter a message').not().isEmpty(),]], async(req, res) => {

    const errors = validationResult(req);
    if (!errors.isEmpty()) {
        return res.status(400).json({ errors: errors.array() });
    }

    try {
        const user = await User.findById(req.user.id).select('-password');
        const encrytedText = AES.encrypt(req.body.text);
        
        const message = new Message({
            text: encrytedText,
            user: req.user.id,
            name: user.name,
            avatar: user.avatar
        });

        const msg = await message.save();

        res.json(msg);
        
    } catch (error) {
        console.error(error.message);
        res.status(500).json({ msg: "Internal Sever Error" }) 
        
    }
});

これが私の暗号化関数と復号化関数です

  const crypto = require("crypto");
const algorithm = "aes-256-cbc";
const key = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);

exports.encrypt= function (text) {
  let cipher = crypto.createCipheriv(algorithm, Buffer.from(key), iv);
  let encrypted = cipher.update(text);
  encrypted = Buffer.concat([encrypted, cipher.final()]);
  return { iv: iv.toString("hex"), encryptedData: encrypted.toString('hex') };
}

exports.decrypt = function (text) {
  let iv = Buffer.from(text.iv, 'hex');
  let encryptedText = Buffer.from(text.encryptedData, 'hex');
  let decipher = crypto.createDecipheriv(algorithm, Buffer.from(key), iv);
  let decrypted = decipher.update(encryptedText);
  decrypted = Buffer.concat([decrypted, decipher.final()]);
  return decrypted.toString();
}

メッセージモデル

const mongoose = require('mongoose');

const MessagesSchema = mongoose.Schema({
    user: { type: mongoose.Schema.Types.ObjectId, ref: 'users' },
    text: {type: Object, required: true},
    name: { type: String },
    avatar: { type: String },
    date: { type: Date, default: Date.now }
});

module.exports = Message = mongoose.model('messages', MessagesSchema);

暗号化と復号化は機能しているようです (ここ)。復号化で暗号化と同じキーが使用されているかどうかを確認します。 encrypt() によって返される暗号文と IV も比較します。decrypt() に渡されたものと比較します (つまり、データが変更されたかどうかを確認します)。

– トパコ

2020 年 9 月 5 日 19:45

問題が見つかったと思います。復号化用のアクティブなキーは常に 1 つあるため、データをデータベースに保存し、後で復号化するときにキーが変更されています。これを修正する方法はありますか?

– クリントン・エメナリ

2020 年 9 月 6 日 9:05



------------------------

解決策を見つけました。私はあなたが必要です変更されない永続的な秘密鍵を指定してください

const crypto = require("crypto");
const algorithm = "aes-128-cbc";
const salt = "foobar";
const hash = crypto.createHash("sha1");

hash.update(salt);

// `hash.digest()` returns a Buffer by default when no encoding is given
let key = hash.digest().slice(0, 16);
crypto.createHash('sha256').update(String(secretkey)).digest('base64').substr(0, 32);
const iv = crypto.randomBytes(16);

exports.encrypt= function (text) {
  
  let cipher = crypto.createCipheriv(algorithm, key, iv);
  let encrypted = cipher.update(text);
  encrypted = Buffer.concat([encrypted, cipher.final()]);
  return { iv: iv.toString("hex"), encryptedData: encrypted.toString('hex') };
}

exports.decrypt = function (text) {
  let iv = Buffer.from(text.iv, 'hex');
  let encryptedText = Buffer.from(text.encryptedData, 'hex');
  
  let decipher = crypto.createDecipheriv(algorithm, key, iv);
  let decrypted = decipher.update(encryptedText);
  decrypted = Buffer.concat([decrypted, decipher.final()]);
  
  return decrypted.toString();
}

1

secretKey はどこで定義されていますか?コードにはそれが見当たりません。

– トラッパー デイビス

2023 年 1 月 11 日 3:05

総合生活情報サイト - OKWAVES
総合生活情報サイト - OKWAVES
生活総合情報サイトokwaves(オールアバウト)。その道のプロ(専門家)が、日常生活をより豊かに快適にするノウハウから業界の最新動向、読み物コラムまで、多彩なコンテンツを発信。