# CryptoKey

The `CryptoKey` interface represents a cryptographic key that one of the [SubtleCrypto](/en/documentation/devtools/runtime/api-reference/subtle-crypto/) methods returns. In an Azion function, a `CryptoKey` is the object you pass to SubtleCrypto when you encrypt, decrypt, sign, or verify data. For more information, refer to [CryptoKey](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey) on MDN Web Docs.

Use a `CryptoKey` to hold an imported secret key that verifies signed tokens or HMAC signatures. A generated key pair can sign or encrypt payloads before they leave the function. Its `usages` restrict how the key applies, so a key can sign but not decrypt, for example. The function handles the key as an opaque object: the raw key material stays out of the code unless the key is extractable and you export it.

---

## Constructor

`CryptoKey` has no public constructor: `new CryptoKey()` throws `TypeError: Illegal constructor`. A function obtains a key from these SubtleCrypto methods:

| Method                        | Returns                                                                                                                                                              |
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `crypto.subtle.generateKey()` | A new `CryptoKey` for a symmetric algorithm, such as AES-GCM or AES-KW. For an asymmetric algorithm, such as ECDSA, an object with a `privateKey` and a `publicKey`. |
| `crypto.subtle.importKey()`   | A `CryptoKey` built from key data you supply, such as the raw bytes of a secret.                                                                                     |
| `crypto.subtle.deriveKey()`   | A `CryptoKey` derived from a base key, such as an AES-GCM key derived with PBKDF2.                                                                                   |
| `crypto.subtle.unwrapKey()`   | A `CryptoKey` decrypted from a wrapped key, such as one wrapped with AES-KW.                                                                                         |

---

## Properties

The properties are read-only. They describe what the key is and which operations it may be applied to, so the runtime applies a key only to the operations it was created for:

| Property                                                                                | Type             | Description                                                                                                                                                                                                                         |
| --------------------------------------------------------------------------------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [`type`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey/type)               | String           | Kind of key: `secret` for a symmetric key, `private` or `public` for one half of a key pair.                                                                                                                                        |
| [`extractable`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey/extractable) | Boolean          | `true` when `crypto.subtle.exportKey()` or `crypto.subtle.wrapKey()` may export the key. The method that creates the key sets it. Exporting a key whose value is `false` rejects with `InvalidAccessError: Key is not extractable`. |
| [`algorithm`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey/algorithm)     | Object           | Algorithm the key is used with, in `name`, and its parameters, such as `length` and `hash`.                                                                                                                                         |
| [`usages`](https://developer.mozilla.org/en-US/docs/Web/API/CryptoKey/usages)           | Array of strings | Operations the key may perform: `encrypt`, `decrypt`, `sign`, `verify`, `deriveKey`, `deriveBits`, `wrapKey`, and `unwrapKey`. The method that creates the key sets them.                                                           |

---

## Example

This handler imports a secret as an HMAC key and signs a message. It checks the signature against the message and a tampered one, then returns the results and the key properties:

```javascript
const enc = new TextEncoder();
const hex = (buf) => Array.from(new Uint8Array(buf), (b) => b.toString(16).padStart(2, '0')).join('');

export default {
  async fetch(request, env, ctx) {
    const key = await crypto.subtle.importKey('raw', enc.encode('a secret'), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign', 'verify']);
    const sig = await crypto.subtle.sign('HMAC', key, enc.encode('Azion Functions'));
    const ok = await crypto.subtle.verify('HMAC', key, sig, enc.encode('Azion Functions'));
    const bad = await crypto.subtle.verify('HMAC', key, sig, enc.encode('tampered'));
    return Response.json({
      signatureHex: hex(sig),
      verifies: ok,
      rejectsTampered: !bad,
      key: { type: key.type, extractable: key.extractable, algorithm: key.algorithm, usages: key.usages, ctor: key.constructor.name },
    });
  },
};
```

The function returns these values. The key is a `CryptoKey` of type `secret`, and it is not extractable because `importKey()` received `false`:

```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

- [SubtleCrypto](/en/documentation/devtools/runtime/api-reference/subtle-crypto.md): The methods that create a `CryptoKey` and the operations that use it.
- [Crypto](/en/documentation/devtools/runtime/api-reference/crypto.md): The global `crypto` object that gives access to SubtleCrypto.
- [node:crypto](/en/documentation/devtools/runtime/node/crypto.md): The Node.js crypto module, for code written against Node.js.
- [Web APIs](/en/documentation/devtools/runtime/api-reference/javascript.md): The other Web APIs that Azion Runtime supports.
