0

The Math.floor(Math.random() * 100) or Math.ceil(Math.random() * 100) method of generating a random number isn't the most cryptographically secure. I want to use this method in a random Password application, I'm trying to use the window.crypto property. Here's what I have set up, but it seems to return an empty value and I'm not sure what I'm doing wrong.

const array = new Uint32Array(1);
window.crypto.getRandomValues(array);

let chars = '0123456789abcdefghijklmnopqrstuvwxyz!@#$%^&*()ABCDEFGHIJKLMNOPQRSTUVWXYZ';
let pwordLength = 12;
let password = '';

for (let i = 0; i <= pwordLength; i++) {
  let randomNumber = array * chars.length;
  password += chars.substring(randomNumber, randomNumber + 1);
}
console.log(`Password is ${password}`);
Millhorn
  • 2,953
  • 7
  • 39
  • 77

1 Answers1

3

You can generate a Uint32Array with the same length as your chars list. Then loop over them to get a random value. By using % we can ensure we never exceed the given length (remainder operator)

let chars = '0123456789abcdefghijklmnopqrstuvwxyz!@#$%^&*()ABCDEFGHIJKLMNOPQRSTUVWXYZ';
let pwordLength = 12;
let password = '';

const array = new Uint32Array(chars.length);
window.crypto.getRandomValues(array);

for (let i = 0; i < pwordLength; i++) {
  password += chars[array[i] % chars.length];
}


console.log(`Password is ${password}`);
Reyno
  • 6,119
  • 18
  • 27
  • 1
    note that (in the general case) using `%` will lead to bias and isn't recommended, but here it's probably OK because `chars.length` is known to be small. we can calculate the probability as the first 40 entries in `chars` being preferred ~1e-8 more – Sam Mason Aug 02 '21 at 08:29