# SubtleCrypto

The `SubtleCrypto` interface holds the low-level cryptographic functions of the Web Crypto API in Azion Runtime. A function reaches it through the `subtle` property of the global [`crypto`](/en/documentation/devtools/runtime/api-reference/crypto/) object. That property holds an instance of `SubtleCrypto`. Use it to hash data, sign and verify messages, encrypt and decrypt, and derive, import, export, and wrap keys. For more information, refer to [SubtleCrypto](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto) on MDN Web Docs.

---

## Methods

`SubtleCrypto` has no parent interface, so it inherits no methods. Every method returns a promise:

| Method                                                                                                                                                                                                  | Description                                                                                                                                                                                                                                                                                                                                                           |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`crypto.subtle.encrypt(algorithm, key, data)`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/encrypt)                                                                                  | Fulfills with the encrypted form of `data`, produced with `key` and `algorithm`. `AES-GCM` encrypts with a 256-bit key and an `iv`.                                                                                                                                                                                                                                   |
| [`crypto.subtle.decrypt(algorithm, key, data)`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/decrypt)                                                                                  | Fulfills with the clear data recovered from the encrypted `data`, using `key` and `algorithm`.                                                                                                                                                                                                                                                                        |
| [`crypto.subtle.sign(algorithm, key, data)`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/sign)                                                                                        | Fulfills with the signature of `data`, computed with `key` and `algorithm`. `HMAC`, `ECDSA`, `RSA-PSS`, and `Ed25519` sign data. An `RSA-PSS` signature with a 2048-bit key is 256 bytes, and an `Ed25519` signature is 64 bytes.                                                                                                                                     |
| [`crypto.subtle.verify(algorithm, key, signature, data)`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/verify)                                                                         | Fulfills with `true` when `signature` matches `data` under `key` and `algorithm`, and with `false` when it does not, such as after `data` changes.                                                                                                                                                                                                                    |
| [`crypto.subtle.digest(algorithm, data)`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest)                                                                                         | Fulfills with the digest of `data` computed with `algorithm`. `SHA-1`, `SHA-256`, `SHA-384`, and `SHA-512` produce 20, 32, 48, and 64 bytes. `MD5` rejects with `NotSupportedError: Unrecognized algorithm name`.                                                                                                                                                     |
| [`crypto.subtle.generateKey(algorithm, extractable, keyUsages)`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/generateKey)                                                             | Fulfills with a [`CryptoKey`](/en/documentation/devtools/runtime/api-reference/crypto-key/) for a symmetric algorithm, or a `CryptoKeyPair` with `privateKey` and `publicKey` for an asymmetric one. The keys take the algorithm, usages, and extractability you pass. It generates `AES-GCM`, `AES-KW`, `ECDSA` on the `P-256` curve, `RSA-PSS`, and `Ed25519` keys. |
| [`crypto.subtle.deriveKey(algorithm, baseKey, derivedKeyAlgorithm, extractable, keyUsages)`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveKey)                                   | Fulfills with a `CryptoKey` derived from `baseKey` with `algorithm`. `PBKDF2` with `SHA-256` derives a 256-bit `AES-GCM` key.                                                                                                                                                                                                                                         |
| [`crypto.subtle.deriveBits(algorithm, baseKey, length)`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/deriveBits)                                                                      | Fulfills with a buffer of pseudo-random bits derived from `baseKey` with `algorithm`. `length` is the number of bits.                                                                                                                                                                                                                                                 |
| [`crypto.subtle.importKey(format, keyData, algorithm, extractable, keyUsages)`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey)                                                | Fulfills with a `CryptoKey` built from `keyData` in `format`. The key takes the algorithm, usages, and extractability you pass. It imports a `raw` key for `HMAC` or `PBKDF2`.                                                                                                                                                                                        |
| [`crypto.subtle.exportKey(format, key)`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/exportKey)                                                                                       | Fulfills with the key data of `key` in `format`, such as `raw` or `jwk`. `exportKey()` rejects a key created with `extractable` set to `false`, with `InvalidAccessError: Key is not extractable`.                                                                                                                                                                    |
| [`crypto.subtle.wrapKey(format, key, wrappingKey, wrapAlgorithm)`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/wrapKey)                                                               | Fulfills with `key` exported in `format` and encrypted with `wrappingKey` and `wrapAlgorithm`. Use it to transfer or store a symmetric key in an untrusted environment. A 256-bit `AES-GCM` key wrapped in `raw` format with `AES-KW` is 40 bytes.                                                                                                                    |
| [`crypto.subtle.unwrapKey(format, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages)`](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/unwrapKey) | Fulfills with the `CryptoKey` that `wrappedKey` holds, decrypted with `unwrappingKey` and `unwrapAlgorithm`.                                                                                                                                                                                                                                                          |

---

## Example

This handler imports a secret as an `HMAC` key, signs a message, and verifies the signature against the message and against altered data. It returns the signature, the two results, and the properties of the key with `Response.json()`:

```javascript
export default {
  async fetch(request, env, ctx) {
    const encoder = new TextEncoder();
    const hex = (buffer) =>
      Array.from(new Uint8Array(buffer), (byte) => byte.toString(16).padStart(2, '0')).join('');

    const key = await crypto.subtle.importKey(
      'raw',
      encoder.encode('a secret'),
      { name: 'HMAC', hash: 'SHA-256' },
      false,
      ['sign', 'verify'],
    );
    const signature = await crypto.subtle.sign('HMAC', key, encoder.encode('Azion Functions'));
    const verifies = await crypto.subtle.verify('HMAC', key, signature, encoder.encode('Azion Functions'));
    const tampered = await crypto.subtle.verify('HMAC', key, signature, encoder.encode('tampered'));

    return Response.json({
      signatureHex: hex(signature),
      verifies,
      rejectsTampered: !tampered,
      key: {
        type: key.type,
        extractable: key.extractable,
        algorithm: key.algorithm,
        usages: key.usages,
        ctor: key.constructor.name,
      },
    });
  },
};
```

The function returns these values. `rejectsTampered` is `true` because `verify()` returns `false` for the altered data:

```json
{
 "signatureHex": "86fec9e22ad82998c7007d637f61a5206e2b64ee2a8ac2ed12f1f359e3d14bc6",
 "verifies": true,
 "rejectsTampered": true,
 "key": {
  "type": "secret",
  "extractable": false,
  "algorithm": {
   "name": "HMAC",
   "length": 64,
   "hash": {
    "name": "SHA-256"
   }
  },
  "usages": [
   "sign",
   "verify"
  ],
  "ctor": "CryptoKey"
 }
}
```

---

## Related resources

- [Crypto](/en/documentation/devtools/runtime/api-reference/crypto.md): The global `crypto` object, its random values, and its `subtle` property.
- [CryptoKey](/en/documentation/devtools/runtime/api-reference/crypto-key.md): The key object that the `SubtleCrypto` methods create and accept.
- [node:crypto](/en/documentation/devtools/runtime/node/crypto.md): The Node.js crypto module that Azion Runtime provides through polyfills.
- [Web APIs](/en/documentation/devtools/runtime/api-reference/javascript.md): The other Web APIs that Azion Runtime supports.
