# Web Crypto

> How Elide supports the Web Crypto API: getRandomValues, randomUUID, and the digest, key, sign, encrypt and derive algorithms of `crypto.subtle`.

The global `crypto` provides `getRandomValues()`, `randomUUID()`, and `crypto.subtle` from the
[Web Cryptography API](https://w3c.github.io/webcrypto/); validation, error names, and messages match Node.

| Operation | Algorithms |
|---|---|
| `digest` | SHA-1, SHA-256, SHA-384, SHA-512, SHA3-256/384/512, cSHAKE128/256 (no function name or customization) |
| `generateKey`, `importKey`, `exportKey` | RSASSA-PKCS1-v1_5, RSA-PSS, RSA-OAEP, ECDSA, ECDH (P-256, P-384, P-521), Ed25519, X25519, HMAC, AES-CTR/CBC/GCM/KW, ChaCha20-Poly1305; HKDF and PBKDF2 import only |
| `sign`, `verify` | RSASSA-PKCS1-v1_5, RSA-PSS, ECDSA, Ed25519, HMAC |
| `encrypt`, `decrypt` | RSA-OAEP, AES-CTR, AES-CBC, AES-GCM, ChaCha20-Poly1305 |
| `wrapKey`, `unwrapKey` | AES-KW and every `encrypt`/`decrypt` algorithm |
| `deriveBits`, `deriveKey` | ECDH, X25519, HKDF, PBKDF2 |
| `getPublicKey`, `SubtleCrypto.supports` | As in Node |

Key formats: `raw` (with `raw-public` and `raw-secret` aliases), `spki`, `pkcs8`, and `jwk`.

## Example

```js
// webcrypto.mjs
const data = new TextEncoder().encode("elide");
const digest = await crypto.subtle.digest("SHA-256", data);
console.log(Buffer.from(digest).toString("hex").slice(0, 16));

const key = await crypto.subtle.generateKey({ name: "ECDSA", namedCurve: "P-256" }, false, ["sign", "verify"]);
const signature = await crypto.subtle.sign({ name: "ECDSA", hash: "SHA-256" }, key.privateKey, data);
console.log(signature.byteLength, await crypto.subtle.verify({ name: "ECDSA", hash: "SHA-256" }, key.publicKey, signature, data));

console.log(crypto.randomUUID().length, crypto.getRandomValues(new Uint8Array(4)).length);
```

`elide run webcrypto.mjs` prints:

```text
bdfdf1cc04d072e4
64 true
36 4
```

## Differences from Node

- `CryptoKey` and [node:crypto](https://elide.help/docs/api-node-crypto) `KeyObject` share key material: `KeyObject.from(cryptoKey)` and
  `keyObject.toCryptoKey()` convert without copying.
- Ed448, X448, AES-OCB, KMAC, Argon2, ML-DSA, ML-KEM, TurboSHAKE, and KangarooTwelve reject with `NotSupportedError`.
  Use `node:crypto` `generateKeyPair` for ML-DSA and ML-KEM keys.

## Samples

- [Sign data with Web Crypto](https://elide.help/docs/code-samples#sign-data-with-web-crypto)

<!-- api-reference:start c722e9014b50 -->
## Reference

**Status:** Full · Not measured · since 1.1.0

### Exports

| Export | Kind | Status | Notes |
| --- | --- | --- | --- |
| `crypto` | object | Full | `randomUUID()`, `getRandomValues()`, `subtle` |
| `SubtleCrypto` | class | Full | `digest()`, `encrypt()`, `decrypt()`, `sign()`, `verify()`, `generateKey()`, `importKey()`, `exportKey()`, `deriveBits()`, `deriveKey()`, `wrapKey()`, `unwrapKey()` |
<!-- api-reference:end -->
