This specification describes an API for generating character encoded Universally Unique Identifiers (UUID) based on [[RFC4122]], available as a method on the Crypto interface.

Introduction

This section is non-normative.

1.1 Motivation

UUID generation is a common software requirement

The uuid library on npm currently receives 131,000,000 monthly downloads and is relied on by over 2,600,000 repositories (as of June 2019).

The ubiquitous nature of the `uuid` module demonstrates that UUID generation is a common requirement for JavaScript software applications, making the functionality a good candidate for the standard library.

Developers "re-inventing the wheel" is potentially harmful

Developers who have not been exposed to [[RFC4122]] might naturally opt to invent their own approaches to UUID generation, potentially using Math.random() (in TIFU by using Math.random() there's an in-depth discussion of why a Cryptographically-Secure-Pseudo-Random-Number-Generator (CSPRNG) should be used when generating UUIDs. Of primary concern is that, without a high-quality source of randomness, collisions can frequently occur.

Introducing a UUID standard library, which dictates that a CSPRNG must be used, helps protect developers from security pitfalls.

Description

Extensions to the Crypto interface

The Crypto interface is defined in [[!WebCryptoAPI]].

        [Exposed=(Window,Worker)]
        partial interface Crypto {
          [SecureContext] DOMString randomUUID();
        };
      

Note: randomUUID() generates a new version 4 UUID and returns its namespace specific string representation as described in RFC4122.

The randomUUID() method.

The randomUUID() method steps are to return the result of [=generate a random UUID|generating a random UUID=].

To generate a random UUID:

  1. Let array be a list with 16 elements of the type byte.

  2. Overwrite all elements of array with cryptographically secure random values of the type byte.

  3. Set the 4 most significant bits of array[6], which represent the UUID version, to 0b0100.

  4. Set the 2 most significant bits of array[8], which represent the UUID variant, to 0b10.

  5. Return the concatenation of «

    1. hexadecimal representation of array[0], hexadecimal representation of array[1], hexadecimal representation of array[2], hexadecimal representation of array[3],
    2. "-",
    3. hexadecimal representation of array[4], hexadecimal representation of array[5],
    4. "-",
    5. hexadecimal representation of array[6], hexadecimal representation of array[7],
    6. "-"
    7. hexadecimal representation of array[8], hexadecimal representation of array[9],
    8. "-",
    9. hexadecimal representation of array[10], hexadecimal representation of array[11], hexadecimal representation of array[12], hexadecimal representation of array[13], hexadecimal representation of array[14], hexadecimal representation of array[15]

    ».

For the steps described in the [=generate a random UUID=] algorithm, the hexadecimal representation of a byte value is the two-character string created by expressing value in hexadecimal using ASCII lower hex digits, left-padded with "0" to reach two characters.

Security considerations

This section is non-normative.
Denial of service
Generating random values has the potential to perform computationally expensive and/or blocking work (if there is not enough entropy available in the system). As such, hostile applications may attempt to misuse this API and attempt to cause significant amount of work to be performed by an implementation, denying access or services to other applications that are executing. In practice, these concerns can be mitigated by using non-blocking sources of randomness, e.g., "/dev/urandom". See also, WebCrypto Security Considerations.
Insufficient entropy
If randomUUID() is invoked before the underlying system is seeded with enough entropy it may result in colliding UUIDs (due to cycles in the PRNG). Authors of applications that use randomUUID() need to be aware of these risks.

Privacy considerations

This section is non-normative.
Fingerprinting
By exposing additional APIs that reflect capabilities of the underlying platform, this specification may allow malicious applications to determine or distinguish different user agents or devices. One such approach is outlined in Clock Around the Clock: Time-Based Device Fingerprinting which discusses creating a fingerprint based on a PRNG in JavaScript. randomUUID() is not likely to make users more susceptible to fingerprinting than they are through existing cryptography methods. See also, WebCrypto Privacy Considerations.
Use of randomUUID() as user ID
randomUUID() is useful for generating user IDs, but does not directly give any ability to generate global identifiers.