Skip to content

Adding examples to Web Crypto #11293

@burgil

Description

@burgil

Which Cloudflare product(s) does this pertain to?

Workers

Subject Matter

Code Examples

Content Location

https://developers.cloudflare.com/workers/runtime-apis/web-crypto/

Additional information

The Web Crypto API in Cloudflare Workers provides a range of low-level cryptographic functions for various purposes. Here's a summarized overview of its components and functions:

Background:

  • The Web Crypto API offers low-level functions for cryptographic tasks.
  • It's implemented through the SubtleCrypto interface, accessed via crypto.subtle.
  • It's faster than pure JavaScript for cryptographic operations.

Constructors:

  • crypto.DigestStream(algorithm): Generates a hash digest from streaming data.
    • Parameters: algorithm (algorithm-specific format).
      // Create a SHA-256 digest stream and pipe data into it
      const digestStream = new crypto.DigestStream("SHA-256");
      dataStream.pipeTo(digestStream);
      
      // Get the final result
      const digest = await digestStream.digest;
      console.log(new Uint8Array(digest));
    • Explanation: This function is used to generate a hash digest from streaming data. Hashing is commonly used in authentication for password hashing, data integrity checks, and digital signatures.
    • Example: You can use it to hash a user's password before storing it in a database for secure authentication.

Methods:

  • crypto.randomUUID(): Generates a new random UUID (version 4).
    const randomUUID = crypto.randomUUID();
    console.log(randomUUID);
    • Explanation: Generates a random UUID, which can be used in authentication as unique session identifiers or temporary tokens.
    • Example: Generate a unique session token for an authenticated user.
  • crypto.getRandomValues(buffer): Fills an ArrayBufferView with cryptographically sound random values.
    • Parameters: buffer (compatible ArrayBufferView types).
      const array = new Uint8Array(4); // Create a buffer for 4 bytes
      crypto.getRandomValues(array);
      console.log(array);
    • Explanation: Provides cryptographically secure random values, which can be be used in creating authentication tokens or nonces.
    • Example: Generate random tokens for user authentication or secure API access.

SubtleCrypto Methods:

  • These methods are accessed via crypto.subtle.

Cryptographic Functions:

  1. encrypt(algorithm, key, data): Encrypts data.

  2. decrypt(algorithm, key, data): Decrypts data.

    // Example: Encrypt and then decrypt
    const algorithm = { name: 'AES-GCM', iv: ivBuffer };
    const key = await crypto.subtle.generateKey(algorithm, true, ['encrypt', 'decrypt']);
    const data = new TextEncoder().encode('Encrypt this data');
    const encryptedData = await crypto.subtle.encrypt(algorithm, key, data);
    const decryptedData = await crypto.subtle.decrypt(algorithm, key, encryptedData);
    console.log(new TextDecoder().decode(decryptedData));
    • Explanation: Used to encrypt and decrypt data, relevant in secure transmission of authentication tokens.
    • Example: Encrypt sensitive authentication data before storing or transmitting it.
  3. sign(algorithm, key, data): Generates a digital signature.

  4. verify(algorithm, key, signature, data): Verifies a digital signature.

    // Example: Sign and then verify
    const algorithm = { name: 'ECDSA', hash: { name: 'SHA-256' } };
    const keyPair = await crypto.subtle.generateKey(algorithm, true, ['sign', 'verify']);
    const data = new TextEncoder().encode('Sign this data');
    const signature = await crypto.subtle.sign(algorithm, keyPair.privateKey, data);
    const isVerified = await crypto.subtle.verify(algorithm, keyPair.publicKey, signature, data);
    console.log('Is Verified:', isVerified);
    • Explanation: Signature generation and verification are vital for ensuring data authenticity and integrity in authentication processes.
    • Example: Sign authentication requests, and verify the signatures of incoming requests.
  5. digest(algorithm, data): Generates a digest (hash) from data.

    const data = new TextEncoder().encode('Hash this data');
    const hash = await crypto.subtle.digest({ name: 'SHA-256' }, data);
    console.log(new Uint8Array(hash));
    • Explanation: Useful for hashing data for secure storage and comparison, such as password hashing for authentication.
    • Example: Hash and securely store user passwords.
  6. generateKey(algorithm, extractable, keyUsages): Generates cryptographic keys.

    const algorithm = { name: 'AES-GCM', length: 256 };
    const key = await crypto.subtle.generateKey(algorithm, true, ['encrypt', 'decrypt']);
    console.log(key);
    • Explanation: Key generation for encryption, a fundamental part of securing authentication mechanisms.
    • Example: Generate encryption keys for secure communication during the authentication process.
  7. deriveKey(algorithm, baseKey, derivedKeyAlgorithm, extractable, keyUsages): Derives a cryptographic key.

    const baseKey = await crypto.subtle.generateKey({ name: 'AES-GCM', length: 256 }, true, ['encrypt', 'decrypt']);
    const derivedKeyAlgorithm = { name: 'AES-GCM', length: 128 };
    const derivedKey = await crypto.subtle.deriveKey({ name: 'ECDH', public: publicKey }, baseKey, derivedKeyAlgorithm, true, ['encrypt', 'decrypt']);
    console.log(derivedKey);
    • Explanation: Key derivation, often used in authentication to derive session keys.
    • Example: Derive session keys for secure communication after initial authentication.
  8. deriveBits(algorithm, baseKey, length): Derives pseudo-random bits.

    const baseKey = await crypto.subtle.generateKey({ name: 'AES-GCM', length: 256 }, true, ['encrypt', 'decrypt']);
    const derivedBits = await crypto.subtle.deriveBits({ name: 'ECDH', public: publicKey }, baseKey, 256);
    console.log(new Uint8Array(derivedBits));
    • Explanation: Derive pseudo-random bits, which can be relevant for generating secure nonces or tokens.
    • Example: Generate secure nonces for one-time authentication.
  9. importKey(format, keyData, algorithm, extractable, keyUsages): Imports an external key.

    const keyData = /* Import key data */;
    const algorithm = { name: 'AES-GCM', length: 256 };
    const key = await crypto.subtle.importKey('raw', keyData, algorithm, true, ['encrypt', 'decrypt']);
    console.log(key);
    • Explanation: Import keys from external sources, relevant for handling external authentication tokens.
    • Example: Import an external user's authentication token for validation.
  10. exportKey(format, key): Exports a CryptoKey.

    const key = /* Get a CryptoKey */;
    const exportedKey = await crypto.subtle.exportKey('raw', key);
    console.log(exportedKey);
    • Explanation: Export a key for storage or sharing, necessary when managing keys for user authentication.
    • Example: Export a user's public key for others to verify their identity.
  11. wrapKey(format, key, wrappingKey, wrapAlgo): Wraps and encrypts a key.

  12. unwrapKey(format, key, unwrappingKey, unwrapAlgo, unwrappedKeyAlgo, extractable, keyUsages): Unwraps a key.
    Not shown as they involve key wrapping and unwrapping operations, which typically require more complex key management scenarios.

    • Explanation: These functions are used for key management and can be relevant when securely storing or sharing authentication keys.
    • Example: Wrap and unwrap encryption keys used in user authentication.
  13. timingSafeEqual(a, b): Compares two buffers in a timing-attack resistant way.

    const bufferA = new Uint8Array(/* A buffer */);
    const bufferB = new Uint8Array(/* Another buffer */);
    const isEqual = crypto.timingSafeEqual(bufferA, bufferB);
    console.log('Buffers are equal:', isEqual);
    • Explanation: Compares buffers securely, which is relevant when comparing tokens or secrets to prevent timing attacks during authentication.
    • Example: Compare authentication tokens or secrets securely to avoid timing-based attacks.

Supported Algorithms:

  • A variety of cryptographic algorithms, including RSA, ECDSA, AES, HMAC, and various hashing algorithms (SHA-1, SHA-256, SHA-384, SHA-512, MD5, etc.).
  • Support for Secure Curves, EdDSA, X25519, and legacy non-standard EdDSA for Ed25519 curve.

Please note that Cloudflare Workers may have differences in supported algorithms compared to standard browsers. Additionally, MD5 is supported for compatibility with legacy systems, but it is considered weak and not recommended for security. The Web Crypto API is not the same as the Node.js Crypto API, but compatibility is available with the nodejs_compat flag.

In summary, the Cloudflare Web Crypto API provides a comprehensive set of cryptographic functions for various purposes, including encryption, decryption, signing, verification, key generation, and more, with support for a range of cryptographic algorithms.

Metadata

Metadata

Labels

DevRelTasks that need support from developer relations.content:newRequest for new/missing contentexampleproduct:workersRelated to Workers productsize/l

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions