简体   繁体   中英

How to properly decrypt string in NodeJS?

I'm working on a NodeJS & MongoDB project where it is required to encrypt the content of the article that it is about to be published.

However, it should display the content if the proper key-codes are entered.

For example, I have a function to create blog where I call my encryText() function:

exports.createBlog = asyncHandler(async (req, res, next) => {
  if (req.body.text === ``) {
    return next(new ErrorResponse(`Please add some text`, 500));
  }

  // Encrypt text
  req.body.text = encrypText(req.body.text); // The data gets encrypted

  // Create document
  const blog = await Blog.create(req.body);

  blog.save({ validateBeforeSave: true });

  // Send response
  res.status(201).json({ success: true, data: blog });
});

This encrypText() function returns an object that looks like this:

{
    "success": true,
    "data": {
        "iv": "QkBZfnTyqaofnHbDC4y6Iw==",
        "encryptedData": "ebe177048b1063acae4eea3b5303a56b62da0ef7c3fc537b4245cf0cbee0291bf4231d0eb97c53e0c0c33fce50f26561277c25829f7021bbc1532aed6e4dc782"
    }
}

Now, nothing is wrong so far. The encryption works great and the decryption also works amazingly well also. The way to decrypt data is by using the same object returned from the encryptText() function and it does as expected but only during few minutes..

"status": "error",
    "error": {
        "library": "digital envelope routines",
        "function": "EVP_DecryptFinal_ex",
        "reason": "bad decrypt",
        "code": "ERR_OSSL_EVP_BAD_DECRYPT",
        "statusCode": 500,
        "status": "error"
    },
    "message": "error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt",

As you can see, the error gets thrown on my screen after 5mins and/or whenever I reset the server.? Why is it that this happens? I mean the string that I'm trying to decrypt has not changed at all?

const crypto = require('crypto');

// Set encryption algorith
const algorithm = 'aes-256-cbc';

/// Private key
const key = crypto.randomBytes(32);

// Random 16 digit initialization vector
const iv = crypto.randomBytes(16);

exports.encrypText = (text) => {
  const cipher = crypto.createCipheriv(algorithm, key, iv);
  let encryptedData = cipher.update(text, 'utf-8', 'hex');

  encryptedData += cipher.final('hex');

  // convert the initialization vector to base64 string
  const base64data = Buffer.from(iv, 'binary').toString('base64');

  return {
    iv: base64data,
    encryptedData: encryptedData
  };
};

exports.decrypText = (text) => {
  // Convert initialize vector from base64 to buffer
  const originalData = Buffer.from(text.iv, 'base64');

  // Decrypt the string using encryption algorith and private key
  const decipher = crypto.createDecipheriv(algorithm, key, originalData);

  let decryptedData = decipher.update(text.encryptedData, 'hex', 'utf-8');
  decryptedData += decipher.final('utf-8');

  return decryptedData;
};

Solved it by making a my secret key static and also went into a different approach which does exactly what I wanted.

const crypto = require('crypto');

// Set encryption algorith
const algorithm = 'aes-256-ctr';

/// Private key
// const key = crypto.randomBytes(32);
const key = `${process.env.ENCRYPTION_KEY}`;

// Random 16 digit initialization vector
const iv = crypto.randomBytes(16);

exports.encrypText = (text) => {
  const cipher = crypto.createCipheriv(algorithm, key, iv);

  const encryptedData = Buffer.concat([cipher.update(text), cipher.final()]);

  return {
    iv: iv.toString('hex'),
    encryptedData: encryptedData.toString('hex')
  };
};

exports.decrypText = (text) => {
  // Convert initialize vector from base64 to hex
  const originalData = Buffer.from(text.iv, 'hex');

  // Decrypt the string using encryption algorith and private key
  const decipher = crypto.createDecipheriv(algorithm, key, originalData);

  const decryptedData = Buffer.concat([
    decipher.update(Buffer.from(text.encryptedData, 'hex')),
    decipher.final()
  ]);

  return decryptedData.toString();
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM