Improve password generation

Generating an 8-bit random number and reducing it modulo 56
(characters.length) does not choose all numbers 0 to 55 with equal
probability, but chooses 0 to 31 with higher probability than 32 to 55.
This change improves the password generation algorithms by choosing all
characters with equal probability.
This commit is contained in:
Martin Dickopp 2021-01-12 18:37:33 +01:00
parent 7e67e0db12
commit 2130f4970f

View File

@ -181,11 +181,21 @@ export class UserRepositoryService extends BaseRepository<ViewUser, User, UserTi
*/ */
public getRandomPassword(length: number = 10): string { public getRandomPassword(length: number = 10): string {
let pw = ''; let pw = '';
const array = new Uint8Array(length);
window.crypto.getRandomValues(array);
const characters = 'abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'; const characters = 'abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789';
for (let i = 0; i < length; i++) { // set charactersLengthPower2 to characters.length rounded up to the next power of two
pw += characters.charAt(array[i] % characters.length); let charactersLengthPower2 = 1;
while (characters.length > charactersLengthPower2) {
charactersLengthPower2 *= 2;
}
while (pw.length < length) {
const random = new Uint8Array(length - pw.length);
window.crypto.getRandomValues(random);
for (let i = 0; i < random.length; i++) {
const r = random[i] % charactersLengthPower2;
if (r < characters.length) {
pw += characters.charAt(r);
}
}
} }
return pw; return pw;
} }