DEV Community

Discussion on: Public Solving: Generating secure password

Collapse
 
lexlohr profile image
Alex Lohr

First of all: don't jeopardize the security of Santa and his elves by using Math.random() to generate passwords. Use crypto.getRandomValues(typedArray) instead. Also, do not linearly cycle the options, as this reduces the randomness again; instead just make sure that each option is used once and afterwards, select the option randomly. Then, there's another small issue in your first check, as options could also contain { numbers: false }.

const optionValues = {
  lowercase: 'abcdefghijklmnopqrstuvwxyz',
  uppercase: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
  numbers: '0123456789',
  specialCharacters: '!@#$%^&*()'
}

export const generatePassword = (length, options) => {
  const selectedOptionsCount =
    Object.values(options).filter(Boolean).length
  if (length < selectedOptionsCount) {
      throw new Error(
        'length is too short to include selected options'
      )
  } else if (selectedOptionsCount === 0) {
      throw new Error('please select at least one option')
  }
  const rand = new Uint16Array(length)
  crypto.getRandomValues(rand)
  const optionKeys = Object.keys(options)
    .filter((key) => options[key])
  return [...new Array(length)]
    .map((_, i) => {
      // make sure to include at least one of each selected option
      // and randomize the rest
      const currentOption = i < selectedOptionsCount
        ? optionValues[optionKeys[i]]
        : optionValues[optionKeys[rand[i] % optionKeys.length]]
      return currentOption[(rand[i] >> 2) % currentOption.length]
    })
    // shuffle for extra randomness
    .sort(() => 0.5 - Math.random())
    .join('')
}
Enter fullscreen mode Exit fullscreen mode

Now we can rest ye merry, gentlemen, as Santa's secrets are very secure.

Collapse
 
dailydevtips1 profile image
Chris Bongers

Nice one!
What's the bad thing about using Math.random?

Do like your super randomness function, smart to use the remained for that.
I think I hit a use-case when trying that where a option would not be added.

So thanks for this solution, great idea to make sure at least the options are set once and then re-shuffle for extra randomness.

Collapse
 
lexlohr profile image
Alex Lohr

Math.random is not random enough, it's just a seeded pseudo-random number generator. So if an attacker knows your code, they can reduce a lot of the possible combinations they would need to try. The same goes for cycling the options, just even worse so, because instead of 72 possible characters for each positions, there would now be only 26 or even 10 left.

Thread Thread
 
dailydevtips1 profile image
Chris Bongers

They should really rename that function 😂
Yeah I've taken in account it would not be the most "random" version because of the looping method always being the same.

Thanks Alex 👏