# @turnkey/crypto

> Encryption, decryption, and key related utility functions

Latest version **2.13.2** (published 2026-09-22) · Apache-2.0 license · 0 weekly downloads

## Install

```sh
npm install @turnkey/crypto
pnpm add @turnkey/crypto
yarn add @turnkey/crypto
bun add @turnkey/crypto
```

## Health

**Score 75/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; has provenance; recently updated; high maintenance score; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 2.13.2 |
| Published | 2026-09-22 |
| First published | 2024-05-08 |
| Weekly downloads | 0 |
| License | Apache-2.0 |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | >=18.0.0 |
| Dependencies | 8 |
| Unpacked size | 344.7 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 102 |
| Author | Turnkey |
| Maintainers | andrewtk, r-n-o, jack-kearney-tkhq |

## Links

- npm: https://www.npmjs.com/package/@turnkey/crypto
- Repository: https://github.com/tkhq/sdk
- Issues: https://github.com/tkhq/sdk/issues
- npm.io page: https://npm.io/package/@turnkey/crypto

## Dependencies (8)

- [borsh](https://npm.io/package/borsh.md) 2.0.0
- [cbor-js](https://npm.io/package/cbor-js.md) 0.1.0
- [@noble/curves](https://npm.io/package/@noble/curves.md) 1.9.0
- [@noble/hashes](https://npm.io/package/@noble/hashes.md) 1.8.0
- [@noble/ciphers](https://npm.io/package/@noble/ciphers.md) 1.3.0
- [@peculiar/x509](https://npm.io/package/@peculiar/x509.md) 1.12.3
- [@turnkey/encoding](https://npm.io/package/@turnkey/encoding.md) 0.6.0
- [@turnkey/sdk-types](https://npm.io/package/@turnkey/sdk-types.md) 1.10.0

## Recent versions

- 2.13.2 (latest) — 2026-09-22
- 2.6.0-beta.6 (beta) — 2025-09-05
- 2.13.1 — 2026-09-22
- 2.13.0 — 2026-09-15
- 2.12.1 — 2026-09-04
- 2.12.0 — 2026-08-27
- 2.11.3 — 2026-08-14
- 2.11.2 — 2026-08-12
- 2.11.1 — 2026-08-06
- 2.11.0 — 2026-08-06
- 2.10.1 — 2026-07-16
- 2.10.0 — 2026-06-02
- 2.9.0 — 2026-05-05
- 2.8.14 — 2026-03-30
- 2.8.13 — 2026-03-25
- … 34 more at https://npm.io/package/@turnkey/crypto/versions

## README

# @turnkey/crypto

This package consolidates some common cryptographic utilities used across our applications, particularly primitives related to keys, encryption, and decryption in a pure JS implementation. For react-native you will need to polyfill our random byte generation by importing [react-native-get-random-values](https://www.npmjs.com/package/react-native-get-random-values)

Example usage (Hpke E2E):

```
const receiverKeyPair = generateP256KeyPair();

const receiverPublicKeyUncompressed = uncompressRawPublicKey(
  uint8ArrayFromHexString(receiverKeyPair.publicKey),
);

const plainText = "Hello, this is a secure message!";
const plainTextBuf = textEncoder.encode(plainText);
const encryptedData = hpkeEncrypt({
  plainTextBuf,
  targetKeyBuf: receiverPublicKeyUncompressed,
});

// Extract the encapsulated key buffer and the ciphertext
const encappedKeyBuf = encryptedData.slice(0, 33);
const ciphertextBuf = encryptedData.slice(33);

const decryptedData = hpkeDecrypt({
  ciphertextBuf,
  encappedKeyBuf: uncompressRawPublicKey(encappedKeyBuf),
  receiverPriv: receiverKeyPair.privateKey,
});

// Convert decrypted data back to string
const decryptedText = new TextDecoder().decode(decryptedData);
```

## Verifying Turnkey webhooks

Use `@turnkey/crypto` directly when you want to manage verification-key fetching and caching yourself. Verification must use the exact raw request body bytes that Turnkey sent, the Turnkey signature headers, Turnkey webhook verification keys, and an explicit `maxTimestampAgeMs` replay window.

Turnkey sends these signature headers with the body: `x-turnkey-timestamp`, `x-turnkey-event-id`, `x-turnkey-signature-key-id`, `x-turnkey-signature-algorithm`, `x-turnkey-signature-version`, and `x-turnkey-signature`. Pass the complete headers object through as received.

`x-turnkey-event-id` is stable across retry attempts for the same webhook event. Use it as the deduplication or idempotency key after signature verification succeeds.

```ts
import { verifyTurnkeyWebhookSignature } from "@turnkey/crypto";

const body = req.body; // Buffer from express.raw(), not parsed JSON
const verificationKeys = [
  {
    keyId: process.env.TURNKEY_WEBHOOK_KEY_ID!,
    publicKey: process.env.TURNKEY_WEBHOOK_PUBLIC_KEY!, // Hex-encoded Ed25519 public key
    algorithm: "ed25519",
  },
];

const result = verifyTurnkeyWebhookSignature({
  headers: req.headers,
  body,
  verificationKeys,
  maxTimestampAgeMs: 5 * 60 * 1000,
});

if (!result.ok) {
  throw new Error(`Invalid Turnkey webhook: ${result.reason}`);
}

const event = JSON.parse(body.toString("utf8"));
```

Do not verify a parsed and re-stringified JSON object. Even harmless-looking changes to whitespace or key ordering will change the signed payload.

---
_Source: https://npm.io/package/@turnkey/crypto · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
