6
const crypto = require('crypto');

async function getKey(byteSize) {
    let key = await crypto.randomBytes(byteSize);
    return key;
}

async function g() {
    let key = await getKey(12);
    return key;
}

console.log(g());

console.log('hello - want this called after g() above');

I've been at this for an hour and I can't understand how to ensure that I get a key using async/await. I get a Promise-pending no matter what I do.

I've also tried this:

async function getKey(byteSize) {
    let key = await crypto.randomBytes(byteSize);
    return key;
}

getKey(12).then((result) => { console.log(result) })


console.log('hello');

... to no avail! Which was inspired by: How to use await with promisify for crypto.randomBytes?

Can anyone help me with this?

All I'm trying to do is to get randomBytes async. using the async./await block but ensure that it fulfills the promise before I carry on in the code.

peteb
  • 18,552
  • 9
  • 50
  • 62
Gary
  • 909
  • 9
  • 26
  • 3
    Since you're not promisify'ing or passing a callback to `crypto.randomBytes()` it is synchronous so you can't await it. Additionally, you're not properly awaiting the promise returned by `g()` at the top level. That is why you always see the pending Promise in your `console.log()` – peteb Jul 28 '20 at 01:33
  • Is there a simple example available? – Gary Jul 28 '20 at 01:44
  • I've provided an answer that demonstrates my comment. – peteb Jul 28 '20 at 01:57

4 Answers4

7

This is an extension of my comment on the question

Since you're not promisify'ing or passing a callback to crypto.randomBytes() it is synchronous so you can't await it. Additionally, you're not properly awaiting the promise returned by g() at the top level. That is why you always see the pending Promise in your console.log()

You can use util.promisify() to convert crypto.randomBytes() into a promise returning function and await that. There is no need for the async/await in your example because all that is doing is wrapping a promise with a promise.

const { promisify } = require('util')
const randomBytesAsync = promisify(require('crypto').randomBytes)

function getKey (size) { 
  return randomBytesAsync(size)
}

// This will print the Buffer returned from crypto.randomBytes()
getKey(16)
  .then(key => console.log(key))

If you want to use getKey() within an async/await style function it would be used like so

async function doSomethingWithKey () {
  let result
  const key = await getKey(16)
   
  // do something with key

  return result
}
peteb
  • 18,552
  • 9
  • 50
  • 62
0

If the callback function is not provided, the random bytes are generated synchronously and returned as a Buffer

// Synchronous
const {
  randomBytes
} = await import('node:crypto');

const buf = randomBytes(256);
console.log(
  `${buf.length} bytes of random data: ${buf.toString('hex')}`);
Italo José
  • 1,558
  • 1
  • 17
  • 50
-1
  const crypto = require('crypto');
    
    async function getKey(byteSize) {
        const buffer = await new Promise((resolve, reject) => {
    crypto.randomBytes(byteSize, function(ex, buffer) {
      if (ex) {
        reject("error generating token");
      }
      resolve(buffer);
    });
    }
    
    async function g() {
        let key = await getKey(12);
        return key;
    }
Nonik
  • 645
  • 4
  • 11
-1
const crypto = require("crypto");

async function getRandomBytes(byteSize) {
  return await new Promise((resolve, reject) => {
    crypto.randomBytes(byteSize, (err, buffer) => {
      if (err) {
        reject(-1);
      }
      resolve(buffer);
    });
  });
}

async function doSomethingWithRandomBytes(byteSize) {
  if (!byteSize) return -1;
  const key = await getRandomBytes(byteSize);
  //do something with key
}

doSomethingWithRandomBytes(16);