Web Crypto

最終更新日:2024-08-14 19:50:33

The Web Crypto API provides a set of low-level functions for common cryptographic tasks, based on the Web standard Web Crypto API. The Edge Cloud Apps Function runtime implements the full functionality of this API.Compared to cryptographic interfaces implemented purely in JavaScript, the Web Crypto API offers higher performance. If you need to perform CPU-intensive cryptographic operations, consider using the Web Crypto API.

Note: For security reasons, the Web Crypto API can only be used in HTTPS environments.

Description

The Web Crypto API is implemented through the SubtleCrypto interface, accessible via the global crypto.subtle binding. Here is a simple example of calculating a digest (also known as a hash):

// Encoding
const myText = new TextEncoder().encode("Hello world!");

// Generate SHA-256 hash value Promise<ArrayBuffer> using crypto
const myDigest = await crypto.subtle.digest(
  {
    name: "SHA-256",
  },
  myText // The data you want to hash as an ArrayBuffer
);

console.log(new Uint8Array(myDigest));

Common uses include signing requests.

Methods

crypto.randomUUID()

crypto.randomUUID(): string

Return Value: Returns a new random (version 4) UUID as defined in RFC 4122.

Description: Generates a new random (version 4) UUID.

crypto.getRandomValues()

crypto.getRandomValues(buffer: ArrayBufferView): ArrayBufferView

Parameters:

  • buffer: Must be an Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, BigInt64Array, or BigUint64Array.

Return Value: Returns the passed-in ArrayBufferView, filled with cryptographically sound random values.

Description: Fills the passed ArrayBufferView with cryptographically sound random values and returns the buffer.

SubtleCrypto Methods

These methods are all accessed via crypto.subtle, which is also documented in detail on MDN.

encrypt()

crypto.subtle.encrypt(algorithm: object, key: CryptoKey, data: BufferSource): Promise<ArrayBuffer>

Parameters:

  • algorithm: An object describing the algorithm to be used, including any required parameters, in an algorithm-specific format.
  • key: A CryptoKey representing the encryption key.
  • data: A BufferSource representing the data to be encrypted.

Return Value: Returns a Promise that fulfills with the encrypted data corresponding to the clear text, algorithm, and key given as parameters.

Description: Returns a Promise that fulfills with the encrypted data corresponding to the clear text, algorithm, and key given as parameters.

decrypt()

crypto.subtle.decrypt(algorithm: object, key: CryptoKey, data: BufferSource): Promise<ArrayBuffer> 

Parameters:

  • algorithm: An object describing the algorithm to be used, including any required parameters, in an algorithm-specific format.
  • key: A CryptoKey representing the decryption key.
  • data: A BufferSource representing the data to be decrypted.

Return Value: Returns a Promise that fulfills with the clear data corresponding to the ciphertext, algorithm, and key given as parameters.

Description: Returns a Promise that fulfills with the clear data corresponding to the ciphertext, algorithm, and key given as parameters.

sign()

crypto.subtle.sign(algorithm: string | object, key: CryptoKey, data: ArrayBuffer): Promise<ArrayBuffer> 

Parameters:

  • algorithm: A string or object describing the algorithm to be used, including any required parameters, in an algorithm-specific format.
  • key: A CryptoKey representing the key used for signing.
  • data: An ArrayBuffer representing the data to be signed.

Return Value: Returns a Promise that fulfills with the signature corresponding to the text, algorithm, and key given as parameters.

Description: Returns a Promise that fulfills with the signature corresponding to the text, algorithm, and key given as parameters.

verify()

crypto.subtle.verify(algorithm: string | object, key: CryptoKey, signature: ArrayBuffer, data: ArrayBuffer): Promise<boolean> 

Parameters:

  • algorithm: A string or object describing the algorithm to be used, including any required parameters, in an algorithm-specific format.
  • key: A CryptoKey representing the key used for verifying the signature.
  • signature: An ArrayBuffer representing the signature to be verified.
  • data: An ArrayBuffer representing the data to be verified.

Return Value: Returns a Promise that fulfills with a Boolean value indicating if the signature given as a parameter matches the text, algorithm, and key that are also given as parameters.

Description: Returns a Promise that fulfills with a Boolean value indicating if the signature given as a parameter matches the text, algorithm, and key that are also given as parameters.

digest()

crypto.subtle.digest(algorithm: string | object, data: ArrayBuffer): Promise<ArrayBuffer>

Parameters:

  • algorithm: A string or object describing the algorithm to be used, including any required parameters, in an algorithm-specific format.
  • data: An ArrayBuffer representing the data to be hashed.

Return Value: Returns a Promise that fulfills with a digest generated from the algorithm and text given as parameters.

Description: Returns a Promise that fulfills with a digest generated from the algorithm and text given as parameters.

generateKey()

crypto.subtle.generateKey(algorithm: object, extractable: boolean, keyUsages: Array<string>): Promise<CryptoKey> | Promise<CryptoKeyPair>

Parameters:

  • algorithm: An object describing the algorithm to be used, including any required parameters, in an algorithm-specific format.
  • extractable: A boolean value indicating whether the generated key is extractable.
  • keyUsages: An array of strings indicating the possible usages of the new key.

Return Value: Returns a Promise that fulfills with a newly generated CryptoKey for symmetric algorithms, or a CryptoKeyPair, containing two newly generated keys, for asymmetric algorithms. For example, to generate a new AES-GCM key:

let keyPair = await crypto.subtle.generateKey(
  {
    name: 'AES-GCM',
    length: 256,
  },
  true,
  ['encrypt', 'decrypt']
);

Description: Returns a Promise that fulfills with a newly generated CryptoKey, for symmetrical algorithms, or a CryptoKeyPair, containing two newly generated keys, for asymmetrical algorithms.

deriveKey()

crypto.subtle.deriveKey(algorithm: object, baseKey: CryptoKey, derivedKeyAlgorithm: object, extractable: boolean, keyUsages: Array<string>): Promise<CryptoKey> 

Parameters:

  • algorithm: An object describing the algorithm to be used, including any required parameters, in an algorithm-specific format.
  • baseKey: A CryptoKey representing the base key from which to derive the new key.
  • derivedKeyAlgorithm: An object defining the algorithm the derived key will be used for, in an algorithm-specific format.
  • extractable: A boolean value indicating whether the derived key is extractable.
  • keyUsages: An array of strings indicating the possible usages of the new key.

Return Value: Returns a Promise that fulfills with a newly generated CryptoKey derived from the base key and specific algorithm given as parameters.

Description: Returns a Promise that fulfills with a newly generated CryptoKey derived from the base key and specific algorithm given as parameters.

deriveBits()

crypto.subtle.deriveBits(algorithm: object, baseKey: CryptoKey, length: number): Promise<ArrayBuffer> 

Parameters:

  • algorithm: An object describing the algorithm to be used, including any required parameters, in an algorithm-specific format.
  • baseKey: A CryptoKey representing the base key from which to derive the bits.
  • length: The length, in bits, of the bit string to derive.

Return Value: Returns a Promise that fulfills with a newly generated buffer of pseudo-random bits derived from the base key and specific algorithm given as parameters. It returns a Promise that will be fulfilled with an ArrayBuffer containing the derived bits. This method is very similar to deriveKey(), except that deriveKey() returns a CryptoKey object rather than an ArrayBuffer. Essentially, deriveKey() is composed of deriveBits() followed by importKey().

Description: Returns a Promise that fulfills with a newly generated buffer of pseudo-random bits derived from the base key and specific algorithm given as parameters.

importKey()

crypto.subtle.importKey(format: string, keyData: ArrayBuffer, algorithm: object, extractable: boolean, keyUsages: Array<string>): Promise<CryptoKey> 

Parameters:

  • format: A string describing the format of the key to be imported.
  • keyData: An ArrayBuffer representing the key data to import.
  • algorithm: An object describing the algorithm to be used, including any required parameters, in an algorithm-specific format.
  • extractable: A boolean value indicating whether the imported key is extractable.
  • keyUsages: An array of strings indicating the possible usages of the new key.

Return Value: Returns a Promise that fulfills with a key, transformed from some external, portable format, into a CryptoKey for use with the Web Crypto API.

Description: Transforms a key from some external, portable format into a CryptoKey for use with the Web Crypto API.

exportKey()

crypto.subtle.exportKey(format: string, key: CryptoKey): Promise<ArrayBuffer>

Parameters:

  • format: A string describing the format in which the key will be exported.
  • key: A CryptoKey representing the key to be exported.

Return Value: Returns a Promise that fulfills with the key in a portable format, if the CryptoKey is extractable.

Description: Transforms a CryptoKey into a portable format if the CryptoKey is extractable.

wrapKey()

crypto.subtle.wrapKey(format: string, key: CryptoKey, wrappingKey: CryptoKey, wrapAlgo: object): Promise<ArrayBuffer> 

Parameters:

  • format: A string describing the format in which the key will be exported before being encrypted.
  • key: A CryptoKey representing the key to be exported.
  • wrappingKey: A CryptoKey representing the key that will be used to encrypt the exported key.
  • wrapAlgo: An object describing the algorithm to be used to encrypt the exported key, including any required parameters, in an algorithm-specific format.

Return Value: Returns a Promise that fulfills with the key, transformed into a portable format, and then encrypted with another key. This renders the CryptoKey suitable for storage or transmission in untrusted environments.

Description: Transforms a CryptoKey into a portable format and then encrypts it with another key.

unwrapKey()

crypto.subtle.unwrapKey(format: string, key: CryptoKey, unwrappingKey: CryptoKey, unwrapAlgo: object, 
unwrappedKeyAlgo: object, extractable: boolean, keyUsages: Array<string>): Promise<CryptoKey> 

Parameters:

  • format: A string describing the data format of the key to be unwrapped.
  • key: A CryptoKey representing the key to be unwrapped.
  • unwrappingKey: A CryptoKey representing the key that will be used to unwrap the key.
  • unwrapAlgo: An object describing the algorithm that was used to encrypt the wrapped key, in an algorithm-specific format.
  • unwrappedKeyAlgo: An object describing the key to be unwrapped, in an algorithm-specific format.
  • extractable: A boolean value indicating whether the unwrapped key is extractable.
  • keyUsages: An array of strings indicating the possible usages of the new key.

Return Value: Returns a Promise that fulfills with the key that was wrapped by wrapKey() transformed back into a CryptoKey.

Description: Transforms a key that was wrapped by wrapKey() back into a CryptoKey.

timingSafeEqual()

crypto.subtle.timingSafeEqual(a: ArrayBuffer | TypedArray, b: ArrayBuffer | TypedArray): boolean

Parameters:

  • a: An ArrayBuffer or TypedArray representing the first buffer to compare.
  • b: An ArrayBuffer or TypedArray representing the second buffer to compare.

Return Value: Returns a boolean value indicating whether the two buffers are equal.

Description: Compares two buffers in a way that is resistant to timing attacks. This is a non-standard extension to the Web Crypto API.

Constructors

crypto.DigestStream(algorithm)

Return Value: A DigestStream object.

Description: A non-standard extension to the Crypto API that supports generating a hash digest from streaming data. The DigestStream itself is a WritableStream that does not retain the data written into it. Instead, it generates a hash digest automatically when the flow of data has ended.

Parameters:

  • algorithm: A string or object describing the algorithm to be used, including any required parameters, in an algorithm-specific format.

Usage:

export default {
  async fetch(req) {
    // Fetch from origin
    const res = await fetch(req);

    // We need to read the body twice so we `tee` it (get two instances)
    const [bodyOne, bodyTwo] = res.body.tee();
    // Make a new response so we can set the headers (responses from `fetch` are immutable)
    const newRes = new Response(bodyOne, res);
    // Create a SHA-256 digest stream and pipe the body into it
    const digestStream = new crypto.DigestStream("SHA-256");
    bodyTwo.pipeTo(digestStream);
    // Get the final result
    const digest = await digestStream.digest;
    // Turn it into a hex string
    const hexString = [...new Uint8Array(digest)]
      .map(b => b.toString(16).padStart(2, '0'))
      .join('')
    // Set a header with the SHA-256 hash and return the response
    newRes.headers.set("x-content-digest", `SHA-256=${hexString}`);
    return newRes;
  }
}

Supported Algorithms

Edge Cloud Apps Functions supports a subset of the algorithms defined in the Web Crypto API standard. The following table shows the supported algorithms:

Algorithm encrypt() decrypt() sign() verify() wrapKey() unwrapKey() deriveKey() deriveBits() generateKey() importKey() exportKey() digest()
RSASSA-PKCS1-v1_5
RSA-PSS
RSA-OAEP
ECDSA
ECDH
HMAC
AES-CTR
AES-CBC
AES-GCM
AES-KW
HKDF
PBKDF2
SHA-1
SHA-256
SHA-384
SHA-512
MD5

References