cloudflare / cloudflare-docs

Cloudflare’s documentation
https://developers.cloudflare.com
Creative Commons Attribution 4.0 International
2.96k stars 3.75k forks source link

Adding examples to Web Crypto #11293

Closed burgil closed 1 month ago

burgil commented 11 months ago

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:

Constructors:

Methods:

SubtleCrypto Methods:

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:

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.

burgil commented 11 months ago

I feel like this page: https://developers.cloudflare.com/workers/runtime-apis/web-crypto/#decrypt Lacks a lot of code examples, People needs to know how important it is to use Web Crypto instead of Node Crypto (performance wise) and so I wrote examples for each function using the new AI.. I hope you guys can expand upon that and add some working examples please that will be very helpful to me.

MauScheff commented 7 months ago

Would also be good to document what permissions are needed in order to access web crypto when deploying to pages authenticated via token. I can't figure out what permission is needed, but I know that it works when I login via oAuth. There is also a bug with oauth, just returns error:. So can't login that way anymore.