[Home](https://codefionn.eu/) · [About](https://codefionn.eu/about/) · [GitHub](https://github.com/codefionn)

---

# The importance of randomness in authentication

> Importance of secure random generators when generating authentication keys

*Published on 2023-04-16 · [View as HTML](https://codefionn.eu/the-importance-of-randomness-in-authentication/)*

---


Authentication keys are machine-generated character sequences used for password
resets, account deletions, <abbr title="Application interface">API</abbr> keys
and other use cases. The generated random character sequence must use a secure
random generator to create the key, otherwise anyone can use them.

## Why?

If the attacker knows the algorithm used to generate the authentication key,
which uses pseudo random numbers based on known metrics such as time and
therefor not cryptographically secure, it can be more easily brute forced.

Take for example this time-based generating algorithm:

```js
// Additional is a parameter for additional bytes to avoid collisions. Don't
// be confused by this, its just to add to the productionness of this function.
async function generateSecretKey(additional) {
  // Get current timestamp
  const now = new Date();
  const now_timestamp = now.getTime();

  return await hashSecretKey(now_timestamp, additional);
}

async function hashSecretKey(secret_key, additional) {
  if (!additional) {
    additional = "";
  }

  // Create a hexadecimal array from it
  const hexdec_string = Number(secret_key).toString(16) + additional;
  const hexdec_array = Int16Array.from(hexdec_string);

  // Obfuscate the data with a hashing algorithm
  const byteHash = Array.from(
    new Uint8Array(await crypto.subtle.digest("SHA-256", hexdec_array)),
  );
  const charHash = byteHash.map((b) => b.toString(16).padStart(2, "0")).join(
    "",
  );

  return charHash;
}
```

<!--This generates a string like `{% fakerandom %}`.-->

And the function to guess the hash:

```js
// Guess the hash with a given estimated time when the hash was created
async function guessHash(target_hash, time_created) {
  const start_time = (new Date()).getTime();

  // Guess milliseconds between 2.5 min before up to 3.0 min after the estimated
  // creation time
  const start = time_created - 2500;
  const end = time_created + 3000;

  for (time = start; time <= end; ++time) {
    const hash = await hashSecretKey(time);

    // Imagine a http request here
    let found_hash = hash === target_hash;

    if (found_hash) {
      const end_time = (new Date()).getTime();

      return {
        duration: end_time - start_time,
        requests: time - start + 1,
      };
    }
  }

  return false;
}
```

Pseudo random generators are weak against attacks guessing the seed or the
original data. In this example it just particulary easy to guess the _API-Key_,
because the time - which is kinda known - is used.

## Interactive example

This example generates a hash and records the time with ± 1 Minutes, when it was
generated.

<button id="generate-hash" disabled>Generate API-Key now</button>

<p class="hidden">Your lucky API-Key is: <code id="generate-hash-result"></code></p>

<button id="guess-hash" disabled>Guess API-Key</button>

<p class="hidden">Took <code id="guess-hash-result"></code> seconds to guess the API-Key with <code id="guess-hash-result-requests"></code> requests and 0.1 seconds between each <i>request</i>.</p>
<p id="guess-hash-404" class="hidden">Hash not found!</p>

---

[Impressum](https://codefionn.eu/impressum/) · [Datenschutzerklärung](https://codefionn.eu/datenschutz/) · [Mastodon](https://c.im/@codefionn)

© Copyright 2022-2026 Fionn Langhans
