Below is some code I wrote to generate a random string in JavaScript. Are there any security issues if I use the values received from this method as salts or tokens for users?
String.random = function(length, characters) {
length = length === undefined ? 32 : length;
characters = characters === undefined ? 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' : characters;
var maxIndex = characters.length - 1;
var string = '';
for(var i = 0; i < length; i++) {
string += characters[Number.random(0, maxIndex)];
}
return string;
}
You can use crypto.getRandomValues() to get cryptographically secure random numbers in javascript, but they're not decimal numbers like Math.random(), so it takes more work to deal with them. Here's the plain javascipt solution with crypto.getRandomValues():
function getCryptoRandomBetween(min, max){
//the highest random value that crypto.getRandomValues could store in a Uint32Array
var MAX_VAL = 4294967295;
//find the number of randoms we'll need to generate in order to give every number between min and max a fair chance
var numberOfRandomsNeeded = Math.ceil((max - min) / MAX_VAL);
//grab those randoms
var cryptoRandomNumbers = new Uint32Array(numberOfRandomsNeeded);
crypto.getRandomValues(cryptoRandomNumbers);
//add them together
for(var i = 0, sum = 0; i < cryptoRandomNumbers.length; i++){
sum += cryptoRandomNumbers[i];
}
//and divide their sum by the max possible value to get a decimal
var randomDecimal = sum / (MAX_VAL * numberOfRandomsNeeded);
//if result is 1, retry. otherwise, return decimal.
return randomDecimal === 1 ? getCryptoRandomBetween(min, max) : Math.floor(randomDecimal * (max - min + 1) + min);
}
function getRandomChar(str){
return str.charAt(getCryptoRandomBetween(0, str.length - 1));
}
String.random = function(length, characters) {
for(var i = 0, str = ""; i < length; i++) str += getRandomChar(characters);
return str;
};
console.log(String.random(60, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"));
Pretty rough on the eyes, but it works. If you want a simpler solution, my preference is rando.js. it works for plain javascript as well as Node.js/React. You can use rando(str)
to get a random character from a string, so building a random string the way you want is as simple as:
String.random = function(length, characters) {
for(var i = 0, str = ""; i < length; i++) str += rando(characters);
return str;
};
console.log(String.random(60, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"));
<script src="https://randojs.com/2.0.0.js"></script>
Let me reiterate that the strings both of these solutions generate have enough entropy to be safe for use as passwords, salts, or tokens for users.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With