Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I synchronise crypto.randomBytes() function of crypto module in node js?

crypto = require('crypto')
async function generateToken(){
  await crypto.randomBytes(256,function(ex, buffer) {
    if (ex) {
      console.log("error generating token");
    }

        var token =  crypto
          .createHash('sha1')
          .update(buffer)
          .digest('hex');

        console.log(token);



  }
)}
console.log("before token");
generateToken();
console.log("after token");

In the above code, I wanted to synchronize the generateToken() method. So I added async and await to the function, but I'm not getting the expected output which is

before token 
7f4f27037cd7dd65bd03d7e2fe859e608b9eebe2
after token 

the output I'm getting is

before token 
after token
7f4f27037cd7dd65bd03d7e2fe859e608b9eebe2

What am I doing wrong in the above code?

edit: the following code would work but it is not synchronized.

crypto = require("crypto");
function generateToken() {
  return new Promise((resolve, reject) => {
    crypto.randomBytes(256, function(ex, buffer) {
      if (ex) {
        reject("error generating token");
      }
      const token = crypto
        .createHash("sha1")
        .update(buffer)
        .digest("hex");
      resolve(token);
    });
  });


  console.log(token);
}

console.log("before token");
generateToken().then((token) => {
  console.log(token);
  console.log("after token");
});
like image 824
Anil GR Avatar asked Dec 10 '22 06:12

Anil GR


2 Answers

const crypto = require("crypto");
async function generateToken() {
  const buffer = await new Promise((resolve, reject) => {
    crypto.randomBytes(256, function(ex, buffer) {
      if (ex) {
        reject("error generating token");
      }
      resolve(buffer);
    });
  });
  const token = crypto
    .createHash("sha1")
    .update(buffer)
    .digest("hex");

  console.log(token);
  return token;
}

console.log("before token");
generateToken().then(token => {
  console.log("after token", token);
});

You can also call it in other async function

async function otherFunction() {
  try {
    console.log("before token");
    const token = await generateToken();
    console.log("after token", token);
  } catch (e) {
    console.error(e)
  }
}
like image 190
anttud Avatar answered May 21 '23 17:05

anttud


If you don't specify a function, then a synchronous version of the function is used and it returns the resulting bytes.

token = crypto.randomBytes(256)

That way you don't need any kind of synchronization (everything is a callback, even when called promises, wait, async, whatnot... so synchronous code in an asynchronous world requires each previous callback to start the next asynchronous job, which can be annoying in some simple cases like this one.)

like image 26
Alexis Wilke Avatar answered May 21 '23 19:05

Alexis Wilke