error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt

Viewed 5677

Please I'm trying to store encrypted data in the database and show decrypted data at the front-end. the encryption works fine but the when i try to decrypt is show this error error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt

here is my code:

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" }) 
        
    }
});

here is my encryption and decryption functions

  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();
}

message model

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);

1 Answers

i found the solution. I need to use a permanent secret key that doesn't change

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();
}

Related