@sebastienrousseau/crypto-server 0.0.2 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/README.md +292 -123
  2. package/dist/@types/types.d.ts +34 -14
  3. package/dist/@types/types.d.ts.map +1 -1
  4. package/dist/@types/types.js +15 -0
  5. package/dist/config/auth-policy.d.ts +2 -0
  6. package/dist/config/auth-policy.d.ts.map +1 -0
  7. package/dist/config/auth-policy.js +18 -0
  8. package/dist/config/constants.d.ts +54 -0
  9. package/dist/config/constants.d.ts.map +1 -0
  10. package/dist/config/constants.js +101 -0
  11. package/dist/config/env.d.ts +16 -0
  12. package/dist/config/env.d.ts.map +1 -0
  13. package/dist/config/env.js +74 -0
  14. package/dist/enterprise/metering.d.ts +19 -0
  15. package/dist/enterprise/metering.d.ts.map +1 -0
  16. package/dist/enterprise/metering.js +159 -0
  17. package/dist/enterprise/types.d.ts +78 -0
  18. package/dist/enterprise/types.d.ts.map +1 -0
  19. package/dist/enterprise/types.js +3 -0
  20. package/dist/index.js +38 -74
  21. package/dist/lib/auth.d.ts +14 -0
  22. package/dist/lib/auth.d.ts.map +1 -0
  23. package/dist/lib/auth.js +120 -0
  24. package/dist/lib/logger.d.ts.map +1 -1
  25. package/dist/lib/logger.js +6 -5
  26. package/dist/lib/telemetry.d.ts +4 -0
  27. package/dist/lib/telemetry.d.ts.map +1 -0
  28. package/dist/lib/telemetry.js +92 -0
  29. package/dist/lib/version.d.ts +2 -0
  30. package/dist/lib/version.d.ts.map +1 -0
  31. package/dist/lib/version.js +7 -0
  32. package/dist/routes/index.d.ts.map +1 -1
  33. package/dist/routes/index.js +19 -4
  34. package/dist/routes/probes.d.ts +4 -0
  35. package/dist/routes/probes.d.ts.map +1 -0
  36. package/dist/routes/probes.js +52 -0
  37. package/dist/routes/v1/decrypt.d.ts +2 -2
  38. package/dist/routes/v1/decrypt.d.ts.map +1 -1
  39. package/dist/routes/v1/decrypt.js +49 -6
  40. package/dist/routes/v1/encrypt.d.ts +2 -2
  41. package/dist/routes/v1/encrypt.d.ts.map +1 -1
  42. package/dist/routes/v1/encrypt.js +48 -6
  43. package/dist/routes/v1/generate.d.ts +2 -2
  44. package/dist/routes/v1/generate.d.ts.map +1 -1
  45. package/dist/routes/v1/generate.js +85 -13
  46. package/dist/routes/v1/index.d.ts +4 -0
  47. package/dist/routes/v1/index.d.ts.map +1 -0
  48. package/dist/routes/v1/index.js +19 -0
  49. package/dist/routes/v1/revoke.d.ts +2 -2
  50. package/dist/routes/v1/revoke.d.ts.map +1 -1
  51. package/dist/routes/v1/revoke.js +57 -5
  52. package/dist/routes/v1/verify.d.ts +4 -0
  53. package/dist/routes/v1/verify.d.ts.map +1 -0
  54. package/dist/routes/v1/verify.js +60 -0
  55. package/dist/routes/v2/algorithms.d.ts +4 -0
  56. package/dist/routes/v2/algorithms.d.ts.map +1 -0
  57. package/dist/routes/v2/algorithms.js +15 -0
  58. package/dist/routes/v2/compliance.d.ts +31 -0
  59. package/dist/routes/v2/compliance.d.ts.map +1 -0
  60. package/dist/routes/v2/compliance.js +223 -0
  61. package/dist/routes/v2/encrypt.d.ts +4 -0
  62. package/dist/routes/v2/encrypt.d.ts.map +1 -0
  63. package/dist/routes/v2/encrypt.js +62 -0
  64. package/dist/routes/v2/hash.d.ts +4 -0
  65. package/dist/routes/v2/hash.d.ts.map +1 -0
  66. package/dist/routes/v2/hash.js +34 -0
  67. package/dist/routes/v2/index.d.ts +4 -0
  68. package/dist/routes/v2/index.d.ts.map +1 -0
  69. package/dist/routes/v2/index.js +44 -0
  70. package/dist/routes/v2/kdf.d.ts +4 -0
  71. package/dist/routes/v2/kdf.d.ts.map +1 -0
  72. package/dist/routes/v2/kdf.js +54 -0
  73. package/dist/routes/v2/key-wrap.d.ts +4 -0
  74. package/dist/routes/v2/key-wrap.d.ts.map +1 -0
  75. package/dist/routes/v2/key-wrap.js +97 -0
  76. package/dist/routes/v2/keys.d.ts +4 -0
  77. package/dist/routes/v2/keys.d.ts.map +1 -0
  78. package/dist/routes/v2/keys.js +88 -0
  79. package/dist/routes/v2/mac.d.ts +4 -0
  80. package/dist/routes/v2/mac.d.ts.map +1 -0
  81. package/dist/routes/v2/mac.js +102 -0
  82. package/dist/routes/v2/multi-recipient.d.ts +4 -0
  83. package/dist/routes/v2/multi-recipient.d.ts.map +1 -0
  84. package/dist/routes/v2/multi-recipient.js +88 -0
  85. package/dist/routes/v2/password-encrypt.d.ts +4 -0
  86. package/dist/routes/v2/password-encrypt.d.ts.map +1 -0
  87. package/dist/routes/v2/password-encrypt.js +92 -0
  88. package/dist/routes/v2/password.d.ts +4 -0
  89. package/dist/routes/v2/password.d.ts.map +1 -0
  90. package/dist/routes/v2/password.js +109 -0
  91. package/dist/routes/v2/pq-hash-sign.d.ts +4 -0
  92. package/dist/routes/v2/pq-hash-sign.d.ts.map +1 -0
  93. package/dist/routes/v2/pq-hash-sign.js +131 -0
  94. package/dist/routes/v2/pq-sign.d.ts +4 -0
  95. package/dist/routes/v2/pq-sign.d.ts.map +1 -0
  96. package/dist/routes/v2/pq-sign.js +117 -0
  97. package/dist/routes/v2/pq.d.ts +4 -0
  98. package/dist/routes/v2/pq.d.ts.map +1 -0
  99. package/dist/routes/v2/pq.js +149 -0
  100. package/dist/routes/v2/sealedbox.d.ts +4 -0
  101. package/dist/routes/v2/sealedbox.d.ts.map +1 -0
  102. package/dist/routes/v2/sealedbox.js +145 -0
  103. package/dist/routes/v2/secretbox.d.ts +4 -0
  104. package/dist/routes/v2/secretbox.d.ts.map +1 -0
  105. package/dist/routes/v2/secretbox.js +94 -0
  106. package/dist/routes/v2/signing.d.ts +4 -0
  107. package/dist/routes/v2/signing.d.ts.map +1 -0
  108. package/dist/routes/v2/signing.js +66 -0
  109. package/dist/routes/v2/stream.d.ts +4 -0
  110. package/dist/routes/v2/stream.d.ts.map +1 -0
  111. package/dist/routes/v2/stream.js +206 -0
  112. package/dist/server.d.ts +4 -0
  113. package/dist/server.d.ts.map +1 -0
  114. package/dist/server.js +124 -0
  115. package/dist/utils/route-helpers.d.ts +15 -0
  116. package/dist/utils/route-helpers.d.ts.map +1 -0
  117. package/dist/utils/route-helpers.js +42 -0
  118. package/dist/utils/validation.d.ts +29 -0
  119. package/dist/utils/validation.d.ts.map +1 -0
  120. package/dist/utils/validation.js +162 -0
  121. package/package.json +103 -140
  122. package/dist/@types/types.js.map +0 -1
  123. package/dist/COPYRIGHT +0 -14
  124. package/dist/Report.txt +0 -90
  125. package/dist/config/endpoints.config.d.ts +0 -7
  126. package/dist/config/endpoints.config.d.ts.map +0 -1
  127. package/dist/config/endpoints.config.js +0 -8
  128. package/dist/config/endpoints.config.js.map +0 -1
  129. package/dist/index.js.map +0 -1
  130. package/dist/lib/logger.js.map +0 -1
  131. package/dist/package.json +0 -141
  132. package/dist/routes/index.js.map +0 -1
  133. package/dist/routes/v1/decrypt.js.map +0 -1
  134. package/dist/routes/v1/encrypt.js.map +0 -1
  135. package/dist/routes/v1/generate.js.map +0 -1
  136. package/dist/routes/v1/revoke.js.map +0 -1
package/README.md CHANGED
@@ -1,170 +1,339 @@
1
- ![Banner representing Crypto Service](https://raw.githubusercontent.com/sebastienrousseau/crypto-service/master/assets/crypto-server-logo.svg)
1
+ <!-- SPDX-License-Identifier: Apache-2.0 OR MIT -->
2
2
 
3
- [![Maintained with Lerna](https://img.shields.io/badge/maintained%20with-lerna-blue?style=for-the-badge)](https://lerna.js.org/)
4
- [![License](https://img.shields.io/badge/License-MIT-green.svg?style=for-the-badge&logo=)](https://opensource.org/licenses/MIT)
5
- ![Made with Love](https://raw.githubusercontent.com/sebastienrousseau/crypto-service/master/assets/made-with-love.svg)
3
+ <p align="center">
4
+ <img src="https://raw.githubusercontent.com/sebastienrousseau/crypto-service/main/assets/crypto-server-logo.svg" alt="crypto-server logo" width="360" />
5
+ </p>
6
6
 
7
- ## Welcome to Crypto Server
7
+ <h1 align="center">@sebastienrousseau/crypto-server</h1>
8
8
 
9
- Crypto Server is a [Fastify][3] web server that exposes easy consumable REST
10
- APIs to perform low-level cryptographic operations. It is implemented using
11
- Node.js and relies on [Crypto Lib][2].
9
+ <p align="center">
10
+ A hardened Fastify REST API for cryptographic operations, with rate limiting, OpenAPI schemas, and post-quantum endpoints.
11
+ </p>
12
12
 
13
- It supports the following cryptographic operations:
13
+ <p align="center">
14
+ <a href="https://github.com/sebastienrousseau/crypto-service/actions"><img src="https://img.shields.io/github/actions/workflow/status/sebastienrousseau/crypto-service/ci.yml?branch=main&style=for-the-badge&logo=github" alt="Build" /></a>
15
+ <a href="https://coveralls.io/github/sebastienrousseau/crypto-service?branch=main"><img src="https://img.shields.io/coveralls/github/sebastienrousseau/crypto-service?branch=main&style=for-the-badge" alt="Coverage" /></a>
16
+ <a href="https://www.npmjs.com/package/@sebastienrousseau/crypto-server"><img src="https://img.shields.io/npm/v/@sebastienrousseau/crypto-server.svg?style=for-the-badge&color=f14041&logo=npm" alt="Registry" /></a>
17
+ <a href="https://sebastienrousseau.github.io/crypto-service/"><img src="https://img.shields.io/badge/docs-TypeDoc-blue.svg?style=for-the-badge&labelColor=555555&logo=typescript" alt="Docs" /></a>
18
+ <a href="https://scorecard.dev/viewer/?uri=github.com/sebastienrousseau/crypto-service" title="ossf-scorecard"><img src="https://img.shields.io/badge/OpenSSF-Scorecard-blue?style=for-the-badge&logo=openssf" alt="OpenSSF Scorecard" /></a>
19
+ <a href="https://github.com/sebastienrousseau/crypto-service/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-Apache--2.0%20OR%20MIT-blue.svg?style=for-the-badge" alt="License: Apache-2.0 OR MIT" /></a>
20
+ <a href="https://github.com/sebastienrousseau/crypto-service/blob/main/docs/POLICIES.md"><img src="https://img.shields.io/badge/Node.js-%3E%3D22-93450a.svg?style=for-the-badge&logo=node.js" alt="Node.js 22 or newer" /></a>
21
+ </p>
14
22
 
15
- - Digital Signing,
16
- - Encryption and Decryption,
17
- - Key Generation,
18
- - Key Management,
19
- - Pseudorandom Number Generation,
20
- - Signature Verification.
23
+ ---
21
24
 
22
- Development of this server is hosted by [GitHub][6] at the [following page][7].
23
- Source code is available to everyone under the standard [MIT license][8].
25
+ ## Contents
24
26
 
25
- ## Getting Started
27
+ **Getting started**
26
28
 
27
- Crypto Server is a [Node.js][4] module available through the [npm registry][5].
28
- Before installing, [download and install Node.js][4]. Node.js 12.20.0 or higher
29
- is required.
29
+ - [Install](#install) — installation via pnpm, npm, or yarn
30
+ - [Requirements](#requirements) — runtime floor and environment prerequisites
31
+ - [Quick Start](#quick-start) — minimal working usage sample
30
32
 
31
- Installation is done using either [`npm`][5],
32
- [`yarn`][9] or [`pnpm`][10] package managers to use Crypto Server with Node.js
33
- or the Command Line Interface:
33
+ **The Crypto Service ecosystem**
34
34
 
35
- - `npm i @sebastienrousseau/crypto-server`
36
- - `yarn add @sebastienrousseau/crypto-server`
37
- - `pnpm add @sebastienrousseau/crypto-server`
35
+ - [The Crypto Service ecosystem](#the-crypto-service-ecosystem) — full 14-package suite overview
38
36
 
39
- ## Quick start
37
+ **Package reference**
40
38
 
41
- ### Starting the Crypto Server
39
+ - [Reference & Usage](#overview) — features, configuration, and capabilities
40
+ - [Examples](#examples) — runnable sample code
42
41
 
43
- - Open Terminal for Mac or Command Prompt for Windows,
44
- - Enter one of the following commands to start the Crypto Server:
42
+ **Operational**
45
43
 
46
- #### NPM
44
+ - [Development](#development) — build, lint, format, and test targets
45
+ - [Security](#security) — vulnerability disclosure and cryptographic invariants
46
+ - [Documentation](#documentation) — TypeDoc API docs and ecosystem guides
47
+ - [Stability guarantees](#stability-guarantees) — SemVer axis and release policy
48
+ - [License](#license)
47
49
 
48
- - `npm run start:server`
50
+ ---
49
51
 
50
- #### Yarn
52
+ ## Install
51
53
 
52
- - `yarn start:server`
54
+ ```bash
55
+ pnpm add @sebastienrousseau/crypto-server
56
+ # or
57
+ npm install @sebastienrousseau/crypto-server
58
+ # or
59
+ yarn add @sebastienrousseau/crypto-server
60
+ ```
53
61
 
54
- #### PNPM
62
+ <p align="right"><a href="#contents">Back to Top</a></p>
55
63
 
56
- - `pnpm start:server`
64
+ ---
57
65
 
58
- This will start the Crypto Server on your local machine with the following
59
- environment details:
66
+ ## Requirements
60
67
 
61
- - Protocol: http,
62
- - Hostname: localhost,
63
- - Port: 3000,
64
- - IP: 127.0.0.1.
68
+ - **Node.js**: `^22.0.0` or `>=24.0.0` (active and maintenance LTS releases)
69
+ - **Package Manager**: `pnpm >=9` (recommended) or `npm >=10`
70
+ - **TypeScript**: `>=5.0` (when compiling with TypeScript)
65
71
 
66
- The Crypto Server should be listening on
67
- [http://localhost:3000/](http://localhost:3000/)
72
+ <p align="right"><a href="#contents">Back to Top</a></p>
68
73
 
69
- ## What are the Crypto Service APIs?
74
+ ---
70
75
 
71
- The Crypto Service APIs give you access to a range of security and encryption
72
- solutions to perform low-level cryptographic operations, key storage operations,
73
- protect static data, and securely share secrets.
76
+ ## Quick Start
74
77
 
75
- On arrival of a new API request, the Crypto Server performs the request
76
- operation in the host environment, subsequently the response is transferred back
77
- to the requesting application. All operations that are performed andd coming
78
- through the Crypto Server are monitored so statistics can be made and acted upon
78
+ Start the server:
79
79
 
80
- The APIs created with Crypto Server should be used with HTTPS endpoints only in
81
- a production web server.
80
+ ```bash
81
+ npx crypto-server
82
+ # or, from a clone of this repo:
83
+ pnpm --filter @sebastienrousseau/crypto-server start
84
+ ```
82
85
 
83
- For greater security, you should choose a minimum Transport Layer Security (TLS)
84
- protocol version to be enforced for your API Gateway custom domain. Crypto
85
- Server recommends either a TLS version 1.3 or TLS version 1.3 security policy.
86
+ Hash some data:
86
87
 
87
- ### Commands & Options
88
+ ```bash
89
+ curl -s -X POST http://localhost:3000/v2/hash \
90
+ -H "Content-Type: application/json" \
91
+ -H "x-api-key: your-secret-api-key" \
92
+ -d '{"algorithm":"sha256","data":"Hello, world!"}' | jq
93
+ ```
88
94
 
89
- #### `/generate`
95
+ ```json
96
+ {
97
+ "data": "315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c75894edd3"
98
+ }
99
+ ```
90
100
 
91
- This endpoint allows you to create a new Key Pair.
101
+ <p align="right"><a href="#contents">Back to Top</a></p>
92
102
 
93
- |Content-Type|Value|Description|
94
- |---|---|---|
95
- |type|rsa|The primary key algorithm type: ECC (default) or RSA. |
96
- |bits|2048|Number of bits for RSA keys (defaults to 4096 bits). |
97
- |name|Jane Doe|First name and Last name |
98
- |email|jane@doe.com|Email address |
99
- |passphrase|123456789abcdef|The passphrase used to encrypt the private key. |
100
- |curve|null|Elliptic curve for ECC keys. See Appendix for more detail... |
101
- |expiration|0|Number of seconds from the key creation time. |
102
- |format|armored|Format of the output keys e.g. 'armored' | 'object' | 'binary'.|
103
+ ---
103
104
 
104
- ```shell
105
- curl --location --request GET 'http://localhost:3000/v1/generate' \
106
- --header 'type: rsa' \
107
- --header 'bits: 2048' \
108
- --header 'name: Jane Doe' \
109
- --header 'email: jane@doe.com' \
110
- --header 'passphrase: 123456789abcdef' \
111
- --header 'curve: null' \
112
- --header 'expiration: 0' \
113
- --header 'format: armored'
114
- ```
105
+ ## The Crypto Service ecosystem
115
106
 
116
- #### `/encrypt`
107
+ Crypto Service provides a complete cryptography stack across 14 specialized packages:
117
108
 
118
- This endpoint allows you to encrypt data in a single operation.
109
+ | Package | Role | Description |
110
+ | :-------------------------------------------------------------------------- | :-------------- | :------------------------------------------------------------------------------------------------------------------------------------- |
111
+ | [`@sebastienrousseau/crypto-api`](../crypto-api) | API Schemas | Shared TypeScript types and utilities for the Crypto Service Suite, defining the canonical API surface. |
112
+ | [`@sebastienrousseau/crypto-cli`](../crypto-cli) | Terminal CLI | An interactive command-line interface for cryptographic operations, supporting both legacy OpenPGP and modern post-quantum algorithms. |
113
+ | [`@sebastienrousseau/crypto-edge`](../crypto-edge) | Edge Runtime | Edge-runtime cryptographic operations using the Web Crypto API, optimized for Cloudflare Workers, Vercel Edge, and Deno. |
114
+ | [`@sebastienrousseau/crypto-kms`](../crypto-kms) | Cloud KMS | Unified Key Management Service interface for AWS KMS, GCP Cloud KMS, Azure Key Vault, and HashiCorp Vault. |
115
+ | [`@sebastienrousseau/crypto-lib`](../crypto-lib) | Core Library | A modern cryptographic library for TypeScript, with post-quantum support, zero unsafe dependencies, and 100% test coverage. |
116
+ | [`@sebastienrousseau/crypto-middleware`](../crypto-middleware) | Middleware | Framework-agnostic cryptographic middleware for Express, Fastify, and Koa applications. |
117
+ | [`@sebastienrousseau/crypto-prisma`](../crypto-prisma) | ORM Adapter | Transparent field-level encryption extension for Prisma Client, using XChaCha20-Poly1305. |
118
+ | [`@sebastienrousseau/crypto-react`](../crypto-react) | React Hooks | React hooks and context provider for client-side cryptographic operations with zero boilerplate. |
119
+ | [`@sebastienrousseau/crypto-sdk`](../crypto-sdk) | Client SDK | A zero-dependency, typed HTTP client for the Crypto Service REST API, with full post-quantum support. |
120
+ | **[`@sebastienrousseau/crypto-server`](../crypto-server)** _(this package)_ | **HTTP API** | **A hardened Fastify REST API for cryptographic operations, with rate limiting, OpenAPI schemas, and post-quantum endpoints.** |
121
+ | [`@sebastienrousseau/crypto-testing`](../crypto-testing) | Test Support | Deterministic keys, fast mocks, and test fixtures for crypto-lib |
122
+ | [`@sebastienrousseau/crypto-typeorm`](../crypto-typeorm) | ORM Adapter | TypeORM column-level encryption with a single decorator, powered by crypto-lib. |
123
+ | [`@sebastienrousseau/crypto-vue`](../crypto-vue) | Vue Composables | Vue 3 composables for client-side cryptography |
124
+ | [`@sebastienrousseau/crypto-wasm`](../crypto-wasm) | Acceleration | WebAssembly performance accelerator for crypto-lib |
119
125
 
120
- |Content-Type|Value|Description|
121
- |---|---|---|
122
- |passphrase|123456789abcdef|Passphrase to encrypt the message.|
123
- |message|Hello Crypto Service!|Message to be encrypted.|
124
- |publicKey|{{publicKey}}|A public key.|
125
- |privateKey|{{privateKey}}|A private key.|
126
+ <p align="right"><a href="#contents">Back to Top</a></p>
126
127
 
127
- ```shell
128
- curl --location --request GET 'http://localhost:3000/v1/encrypt' \
129
- --header 'passphrase: 123456789abcdef' \
130
- --header 'message: Hello Crypto Service!' \
131
- --header 'publicKey: LS0tLS1CRUdJTiBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tCgp4c0JOQkdLSHhCUUJDQURmS0VyYUVnT1VYZHFKVGVTdnUzb2NPWGg2VytxWllDbndOUFVvRjZpcnREbGUKNzVVYTByYkFUZEsxbXF4S1g0L0hraGhzQllQRXdNRHE0RnVzbkxOK0ZnNVdmdGpSR0M5NmJENnRmbVIzClJZY0p5WTEwTFlDRS9GS21iLzFJRGIrT2RtRk8weEpPSWxaTERSeVJSN0xwUlRDNE1mMkRiaFNheExqcwpZdFVhaFZPcCtNeHBkNmFWektYYUpkVVVmVWRYbVliRnpaM0YzK1RMa01zMFdaY05vRDJ3bWNpSGJVUXIKT1JnRkhoQ0I2dUNLNEs3d2R4OStjTllkTkQyb2t6WjJTdmRVenQ3QUZrajFra05XeVM3VWprWmVEdm9UCmp5dFNpZXFMQWJ3L2NUaXRrTjJ1MlZJU1UxMHEwbFhMSERaWWFXTll1OHRMaHFYM0F4c3FNQ1V0QUJFQgpBQUhORjBwaGJtVWdSRzlsSUR4cVlXNWxRR1J2WlM1amIyMCt3c0NLQkJBQkNBQWRCUUppaDhRVUJBc0oKQndnREZRZ0tCQllBQWdFQ0dRRUNHd01DSGdFQUlRa1E5L09ucUlLaTh2RVdJUVExYXRBVHl5WTZZcDFoCjN6ZjM4NmVvZ3FMeThZeUFDQUNudlF1aFMxeHV2YnhUQVdZcWkrcjNFUkpOSzVINUFkOWpFNERUWUZPTQowcDRuMmJwSlQwa2t1bkMzckp0Z2tQbnRNVFJ6eEJvS0QrcmRIdS9FZno1MjNPMENJbjlCOG8vWWpvencKQVFBMldHLzhIdlRYOU0yZVUzOVM3SkptS1I4aks5TDVtYlduV1I2eEZadExSc0pIT2FzSm50S1BsUkFSCnpXNmwweTNjRzRueFJieHM2QS9tczFjM05seDdodjErN24yaTN6d3l2aE52Rys5Y0F0TlM3L3NkLzExbgpYQUJ0QWt2WjU3SnUwWXBKQ3JuMHhvblJuN0kyQ1lTd1BNVTZKMTFIL2l5eXdTNFB5aHlrV2lHMmhNNC8KM3ZMVDdpQVoxZlhkczk0SDFQTW9zNEZMbU50YkphSC83OXRyRFNpem1zY0ExbG9IUlFSOHVvNElKNkx6CnpzQk5CR0tIeEJRQkNBRHNNblVIWkVydTl5V2ljYjRxajJxWGhuanFSOVZHZVdvaEd1UFNRc2dpLzNRRQp4K3FJSjJFeU1LelQ1aXRYT01tQU1pbk5GRGd3ek1FQ081Nk53TWdWUXJnSm5LdnNGR0gxdVFUb0MzaHcKR1pjUDArUTB0aThPWmFLOUZFbngra1FYNXJjYWRGWTBSOW9KTEFNS1JzOU45YmJ2eU40VzRCMW5weklmClF6NWloMUNIQnRqektpVTdaVzBKM1ZLa285NHp4bGZiZVRKS2ZxWnl4eGtuMVVPZWliWWp4dGYrZXZKaQpPOUZMUGpOcGkwem8zZ3kvQ1Y5UGtDUjA3c295aTVJeVVNNE9CRzBoRFNjV2Z4a0xEc0M0b0tzTjJhaGYKeHovSWc0em9FNUk2L0t5c2U1QW1GaWZSaHhaUnRhY3JyOTBqazc4a2Q1S0p6WXhETXhTK0ZzUUJBQkVCCkFBSEN3SFlFR0FFSUFBa0ZBbUtIeEJRQ0d3d0FJUWtROS9PbnFJS2k4dkVXSVFRMWF0QVR5eVk2WXAxaAozemYzODZlb2dxTHk4WDBTQ0FDY0FFTWQ2c2JvVHVOZlVPb2RaQjdvM25NV2RDMEVja1kzSnhLbFE3b0kKV0hpUTNTdU9ibXduWGhSTHJ4TTZ4ZmtUQ3pYK2FUQ2NCemhlZmFMWVU4R1BsSU00SFRhank0MHVNb2Y2CkV3SnpFenpucjhZRVVmdU1Pd094anFrZHpjK2llbk9lT2V6b2dQeTFieGtZTmpHeHpaTFFUekptMkhXWAowOFlNWWtqMXJNTmg0VGZQMnZaYUFHem5LMHBrb0lHdVBHQTdPTTVpRHFIa3pyeWppWG1pV1VVM1lTcHYKMTV5VkEyQXBxN2o1ZFJWd2d4eFpLS2xhOW5iaXhYUEdhTVFSV0w3RUcxM0pMbTFidVlxUXVsVExyMTNkClByKzR2NStlQ3NEZkRpcU9veFYyU000R0ZxanBaRUFBNEZlZFlTMmx1ZXV3WUdvVnRtT1BOdjViME9iUAo9YTZHRQotLS0tLUVORCBQR1AgUFVCTElDIEtFWSBCTE9DSy0tLS0tCg==' \
132
- --header 'privateKey: LS0tLS1CRUdJTiBQR1AgUFJJVkFURSBLRVkgQkxPQ0stLS0tLQoKeGNNR0JHS0h4QlFCQ0FEZktFcmFFZ09VWGRxSlRlU3Z1M29jT1hoNlcrcVpZQ253TlBVb0Y2aXJ0RGxlCjc1VWEwcmJBVGRLMW1xeEtYNC9Ia2hoc0JZUEV3TURxNEZ1c25MTitGZzVXZnRqUkdDOTZiRDZ0Zm1SMwpSWWNKeVkxMExZQ0UvRkttYi8xSURiK09kbUZPMHhKT0lsWkxEUnlSUjdMcFJUQzRNZjJEYmhTYXhManMKWXRVYWhWT3ArTXhwZDZhVnpLWGFKZFVVZlVkWG1ZYkZ6WjNGMytUTGtNczBXWmNOb0Qyd21jaUhiVVFyCk9SZ0ZIaENCNnVDSzRLN3dkeDkrY05ZZE5EMm9reloyU3ZkVXp0N0FGa2oxa2tOV3lTN1Vqa1plRHZvVApqeXRTaWVxTEFidy9jVGl0a04ydTJWSVNVMTBxMGxYTEhEWllhV05ZdTh0TGhxWDNBeHNxTUNVdEFCRUIKQUFIK0NRTUlhRCtXMXJEYitZN2cweXB1M2h0UElQSXZUYm15dkNMOUZKVitLZzdrRFZHVG5QR1Q0NGhMCm9GRXZrNEZIeHdjSHp4SytjLzUvQnltM2JqWlMzMStDNTBqbTQvUDYrVGVPWGRXakVBT1JSQUJxb05pRgpVcUcrSWpiZnlvbkFzSEx5aVcrQ1BDczJyVnlJQTRCdGhHWHBtRmtYQnpIYk5QSTE3cThvS2ZBQnViY3oKeVYrbkxzd1g4TC9md1lRcHRmTjZ2ZGVhNjVUMzdOTGYzWGdkU29SVUx5ZnpsK1VSVEE5dW1kNDRHWUQrCk9pZk1hb2tKZ3E4RENMWHk3R2VYeDh1V1Fod1l3N2hYV3JhWXUyU21VdjdDaWxDeG9QRkNORnh6aFdiQgoraHlpbWVZam9KbS9VeEJtbEZZSHY0c3Mrb21NazhQQ2M3L1Z3WEZ5U0xpL2M5Q3ROakVCamJIaGZ6VlEKSVFtSVd2aUhibkwzSVNmdkFvR2tPMHBQMHhmczh3dGx6RVhqRm9aRXlUeW1vOGhROXV4V1BxNVFjSkxrCkZrcmhZcUZqYndIMjc3Szd2K2dESHp2SDlHSnljYlhMZHpyVzNmMERPM1NUNHlrcHFQaWdTeHRiMkE1Tgo1STlIbTZmOFl1KzVUNWlVajFiUVdJOEErR0VkZXI5VTl0RjdpN2QycHB2S2VvL0ZxUU10eUh2Wm0zaG4KNmNQNFpyd09Kdmk5b0lsaVhXdHZySWM0QU5SV0FSSks5WkswTlZsdlZxOGEzR1l6SUY3ODNzeTM5dTZ2ClJCeHI4dll3WC9KSjNPR2tnVWlhVW12czBTNmhxU0d5RkRubi9kbUZ6elBlTzZ5eGl2WkhkeWs5T0pGSAo4N0hMdmF6WFdhWExkbWlPOU1WWFpRYWM3NlI1RTZodTk0U0ZRWjZ3YWRsTGxWeW43V0MzT1BYeHFzOXYKS2hyRzk2TkJqYTl3bnBqSFVLb1NDbG9PQW16UEVKWW54a2xGQXhucWJNQ1lCUGV4bFpqKzNzbVY4RWVmCnpmSHJrOTdFZmNEWHZtQTAwK0RtaXYzbi9hampQUjIyTTh5QVkyRFFlbHM4YThZbU1ZMm5JTldyVUIySgoxa1VJcW5rVVc0SmtwY29OZUlQbUJKVTZRSC9pYm9zVTdicW56OG1EZm9QenAyWjYwZ0ZNUEpjM0hISTUKb2JtSW9TUFJUWG85THBkWjdZRmUzUnZ0cDFKVHgzM3F6UmRLWVc1bElFUnZaU0E4YW1GdVpVQmtiMlV1ClkyOXRQc0xBaWdRUUFRZ0FIUVVDWW9mRUZBUUxDUWNJQXhVSUNnUVdBQUlCQWhrQkFoc0RBaDRCQUNFSgpFUGZ6cDZpQ292THhGaUVFTldyUUU4c21PbUtkWWQ4MzkvT25xSUtpOHZHTWdBZ0FwNzBMb1V0Y2JyMjgKVXdGbUtvdnE5eEVTVFN1UitRSGZZeE9BMDJCVGpOS2VKOW02U1U5SkpMcHd0NnliWUpENTdURTBjOFFhCkNnL3EzUjd2eEg4K2R0enRBaUovUWZLUDJJNk04QUVBTmxodi9CNzAxL1RObmxOL1V1eVNaaWtmSXl2UworWm0xcDFrZXNSV2JTMGJDUnptckNaN1NqNVVRRWMxdXBkTXQzQnVKOFVXOGJPZ1A1ck5YTnpaY2U0YjkKZnU1OW90ODhNcjRUYnh2dlhBTFRVdS83SGY5ZFoxd0FiUUpMMmVleWJ0R0tTUXE1OU1hSjBaK3lOZ21FCnNEekZPaWRkUi80c3NzRXVEOG9jcEZvaHRvVE9QOTd5MCs0Z0dkWDEzYlBlQjlUektMT0JTNWpiV3lXaAovKy9iYXcwb3M1ckhBTlphQjBVRWZMcU9DQ2VpODhmREJnUmloOFFVQVFnQTdESjFCMlJLN3ZjbG9uRysKS285cWw0WjQ2a2ZWUm5scUlScmowa0xJSXY5MEJNZnFpQ2RoTWpDczArWXJWempKZ0RJcHpSUTRNTXpCCkFqdWVqY0RJRlVLNENaeXI3QlJoOWJrRTZBdDRjQm1YRDlQa05MWXZEbVdpdlJSSjhmcEVGK2EzR25SVwpORWZhQ1N3RENrYlBUZlcyNzhqZUZ1QWRaNmN5SDBNK1lvZFFod2JZOHlvbE8yVnRDZDFTcEtQZU04WlgKMjNreVNuNm1jc2NaSjlWRG5vbTJJOGJYL25yeVlqdlJTejR6YVl0TTZONE12d2xmVDVBa2RPN0tNb3VTCk1sRE9EZ1J0SVEwbkZuOFpDdzdBdUtDckRkbW9YOGMveUlPTTZCT1NPdnlzckh1UUpoWW4wWWNXVWJXbgpLNi9kSTVPL0pIZVNpYzJNUXpNVXZoYkVBUUFSQVFBQi9na0RDSHVaSUcyc3YvenM0SEhaWEpoMFdKa2kKWitkbjFqYUw3RXowdjVuRzBTWDh6cjFaYWwxU2ZmZFNHcDRFampSbEdNRVdhK25pdkhIQW1QcWdXN0JTCldJdmhYNWN6VTQ0NU1ZOG1TOXFjOGRZT1VMa0FOVUhoTzFtZlZ1U2d6RHdPZUl3eTg4NlkydnVLWnJ1UgpsVm1wZjJ2L1lVdDBDNzNkdTVpZ1hoQmlMMVhJbS93MHFwL2FZN1NmRmNUeEJ2UTVjL1BrSUtmZ2pJeDYKOStRejJ4ZllYSnk5M0Z4MjF0MVMwUFFvRHdTcFZvVjdkc1lRS3ZhMWcyRGNpTmM4UW1TYTV1QlN5ckZ4CjJNaG5MdTY4eTg5SnFNNEgzWjBvUTg2RGhxREE0eWFWaFlnRk1qQ0RSRVJRVXFhb1dBWWJqcHQyVHpHWQphb0tZUVI1VGprbDd1VnFQSlZia3BQbFZXdnJNNDVQblpxSkpjSWdlNmIvVHhoNkE5WWVRaTRtVi9LS3MKS1ZqUWd5OXFUT2V3cmZGNERiODVXdjRiekhEckZyR3hGbVNZTWVPY1h2ZVl0TGZPVlM5RmpiQ1pJZ0U1ClBRaUtXWDNzeXViVHg2eEw1aGUxUVl0SUdoaUJmZS9TV3Z0WUoxZlJUT3Y1MFBkM3JRSjB4ZVJmQ2hONgpQbkQ3ZzBGQ2xIeFJvc1k4dld5ZXNUenVpdUMxTWhPTzlqaGNwVGZpR05wU0dpNjdUNlIzcjVmdTNtSmEKb1UrcGlRSGVDaGhjSjRIeFZkQ24rQ05QS1VqQ3N0RnY0MndvRlMvOHZJeksvZkswZjQzVlRERWtVeUtPClUxUWZiNWRianNrYWpTY3NKd09FYklaeFdySkVDcUtPd2RRaHVMakpnLzNlQldtZUh3NCtWeGJsTFo5MQpvVFZWN1B0MjlqUm50WDN4VXl4d2pSVHVVK0toZ3pVSTFySFAzNCt0NTFoYVR1WmlWbTZFaU1MNUxJTkcKenFvbGgwc0pUcW9JZ1BKNTZtQmFieFcxUmtUMCthWEVXWlY4b0RoK0xoY2d0VGoyd201bXgwUnBmZCswCkJGWmQvTE9EaDBrTGF6ZW14TkRReU5MWVRTbXQwK3hqcUIvUnFlVEZkZ0U3dSthMTFTZm1MejJRaDRBVApvRU5qVS9YREFoWERkQlQ0TkhqOGxtbGxWV0RueGJ4b2xPOE9hWGhVREVsOTBCKzN0S2EyY3d4WnI2ckQKZWNMQWRnUVlBUWdBQ1FVQ1lvZkVGQUliREFBaENSRDM4NmVvZ3FMeThSWWhCRFZxMEJQTEpqcGluV0hmCk4vZnpwNmlDb3ZMeGZSSUlBSndBUXgzcXh1aE80MTlRNmgxa0h1amVjeFowTFFSeVJqY25FcVZEdWdoWQplSkRkSzQ1dWJDZGVGRXV2RXpyRitSTUxOZjVwTUp3SE9GNTlvdGhUd1krVWd6Z2ROcVBMalM0eWgvb1QKQW5NVFBPZXZ4Z1JSKzR3N0E3R09xUjNOejZKNmM1NDU3T2lBL0xWdkdSZzJNYkhOa3RCUE1tYllkWmZUCnhneGlTUFdzdzJIaE44L2E5bG9BYk9jclNtU2dnYTQ4WURzNHptSU9vZVRPdktPSmVhSlpSVGRoS20vWApuSlVEWUNtcnVQbDFGWENESEZrb3FWcjJkdUxGYzhab3hCRll2c1FiWGNrdWJWdTVpcEM2Vk11dlhkMCsKdjdpL241NEt3TjhPS282akZYWkl6Z1lXcU9sa1FBRGdWNTFoTGFXNTY3QmdhaFcyWTQ4Mi9sdlE1czg9Cj1rTjFICi0tLS0tRU5EIFBHUCBQUklWQVRFIEtFWSBCTE9DSy0tLS0tCg=='
128
+ ---
129
+
130
+ ## Overview
131
+
132
+ Crypto Server is built on **Fastify 4.x** with a layered middleware
133
+ stack:
134
+
135
+ ```
136
+ Request
137
+ -> @fastify/helmet (security headers)
138
+ -> @fastify/cors
139
+ -> @fastify/rate-limit
140
+ -> @fastify/compress
141
+ -> Authentication (x-api-key / JWT Bearer)
142
+ -> Route handler
143
+ -> Response
133
144
  ```
134
145
 
135
- #### `/decrypt`
146
+ ### Route versioning
147
+
148
+ | Prefix | Status | Notes |
149
+ | :---------------------------- | :------------- | :---------------------------------------------------------------------------- |
150
+ | `/v1/*` | **Deprecated** | Legacy PGP-based endpoints. Emit `Deprecation`, `Sunset`, and `Link` headers. |
151
+ | `/v2/*` | **Current** | Modern endpoints using `@noble/*` primitives and post-quantum algorithms. |
152
+ | `/live`, `/ready`, `/metrics` | Stable | Infrastructure probes (no auth required). |
153
+
154
+ <p align="right"><a href="#contents">Back to Top</a></p>
155
+
156
+ ## API Routes
157
+
158
+ All v2 endpoints accept and return `application/json`. Authenticated
159
+ requests must include an `x-api-key` header (or
160
+ `Authorization: Bearer <jwt>`).
161
+
162
+ | Method | Path | Description |
163
+ | :----- | :---------------------------- | :----------------------------------------------------------- |
164
+ | `POST` | `/v2/hash` | Compute a cryptographic hash (SHA-2, SHA-3, BLAKE2b, BLAKE3) |
165
+ | `POST` | `/v2/encrypt` | AEAD encryption with XChaCha20-Poly1305 |
166
+ | `POST` | `/v2/decrypt` | AEAD decryption with XChaCha20-Poly1305 |
167
+ | `POST` | `/v2/sign` | Create a digital signature |
168
+ | `POST` | `/v2/verify` | Verify a digital signature |
169
+ | `POST` | `/v2/kdf` | Derive a key (scrypt, HKDF-SHA256, PBKDF2-SHA256) |
170
+ | `POST` | `/v2/hmac` | Compute an HMAC |
171
+ | `POST` | `/v2/hmac/verify` | Verify an HMAC in constant time |
172
+ | `POST` | `/v2/password/hash` | Hash a password with Argon2id |
173
+ | `POST` | `/v2/password/verify` | Verify a password against an Argon2id hash |
174
+ | `POST` | `/v2/password/encrypt` | Encrypt with password (Argon2id + XChaCha20-Poly1305) |
175
+ | `POST` | `/v2/password/decrypt` | Decrypt with password |
176
+ | `POST` | `/v2/keys/generate` | Generate a key pair for any supported algorithm |
177
+ | `POST` | `/v2/keys/wrap` | Wrap a key with AES-KW or AES-KWP |
178
+ | `POST` | `/v2/keys/unwrap` | Unwrap a key |
179
+ | `POST` | `/v2/secretbox/seal` | Encrypt with XChaCha20-Poly1305 (secretbox) |
180
+ | `POST` | `/v2/secretbox/open` | Decrypt a secretbox ciphertext |
181
+ | `POST` | `/v2/sealedbox/seal` | Anonymous public-key encryption (X25519) |
182
+ | `POST` | `/v2/sealedbox/open` | Decrypt an anonymous sealed box |
183
+ | `POST` | `/v2/sealedbox/seal-pq` | Post-quantum sealed box (X25519 + ML-KEM-768) |
184
+ | `POST` | `/v2/sealedbox/open-pq` | Decrypt a post-quantum sealed box |
185
+ | `POST` | `/v2/multi-recipient/encrypt` | Encrypt for multiple recipients |
186
+ | `POST` | `/v2/pq/keygen` | Generate an ML-KEM-768 key pair (FIPS 203) |
187
+ | `POST` | `/v2/pq/encapsulate` | Encapsulate a shared secret with ML-KEM-768 |
188
+ | `POST` | `/v2/pq/decapsulate` | Decapsulate and recover the shared secret |
189
+ | `POST` | `/v2/pq/hybrid/keygen` | Generate a hybrid X25519 + ML-KEM-768 key pair |
190
+ | `POST` | `/v2/pq/hybrid/encapsulate` | Hybrid encapsulation |
191
+ | `POST` | `/v2/pq/hybrid/decapsulate` | Hybrid decapsulation |
192
+ | `POST` | `/v2/pq/dsa/keygen` | Generate an ML-DSA key pair (FIPS 204) |
193
+ | `POST` | `/v2/pq/dsa/sign` | Sign with ML-DSA |
194
+ | `POST` | `/v2/pq/dsa/verify` | Verify an ML-DSA signature |
195
+ | `POST` | `/v2/pq/slh-dsa/keygen` | Generate an SLH-DSA key pair (FIPS 205) |
196
+ | `POST` | `/v2/pq/slh-dsa/sign` | Sign with SLH-DSA |
197
+ | `POST` | `/v2/pq/slh-dsa/verify` | Verify an SLH-DSA signature |
198
+ | `GET` | `/v2/algorithms` | List all supported algorithms |
199
+ | `GET` | `/live` | Liveness probe (Kubernetes) |
200
+ | `GET` | `/ready` | Readiness probe (Kubernetes) |
201
+ | `GET` | `/metrics` | Prometheus-compatible metrics |
202
+
203
+ <p align="right"><a href="#contents">Back to Top</a></p>
204
+
205
+ ## Authentication
206
+
207
+ The server supports two authentication modes:
208
+
209
+ 1. **API Key** -- set `CRYPTO_API_KEY` and pass it as the `x-api-key`
210
+ header.
211
+ 2. **JWT Bearer** -- set `JWT_SECRET` and pass
212
+ `Authorization: Bearer <token>`.
213
+
214
+ If neither variable is set, all requests are allowed (development
215
+ mode).
216
+
217
+ ```bash
218
+ # API key
219
+ curl -H "x-api-key: your-secret-api-key" ...
220
+
221
+ # JWT Bearer
222
+ curl -H "Authorization: Bearer eyJhbGciOi..." ...
223
+ ```
224
+
225
+ <p align="right"><a href="#contents">Back to Top</a></p>
226
+
227
+ ## Configuration
228
+
229
+ | Variable | Default | Description |
230
+ | :-------------------- | :------------ | :------------------------------------------------- |
231
+ | `PORT` | `3000` | TCP port to listen on |
232
+ | `HOST` | `localhost` | Bind address |
233
+ | `PROTOCOL` | `http` | `http` or `https` |
234
+ | `NODE_ENV` | `development` | `development`, `production`, or `test` |
235
+ | `LOG_LEVEL` | `info` | `error`, `warn`, `info`, or `debug` |
236
+ | `CRYPTO_API_KEY` | -- | Static API key for `x-api-key` authentication |
237
+ | `JWT_SECRET` | -- | HMAC secret for HS256 JWT validation |
238
+ | `CORS_ORIGIN` | -- | Comma-separated allowed origins (empty = disabled) |
239
+ | `TRUSTED_PROXY_CIDRS` | -- | Comma-separated trusted proxy CIDRs |
240
+ | `CRYPTO_KEY_DIR` | -- | Directory for key storage |
241
+ | `CRYPTO_KEY_OUT_DIR` | -- | Directory for key output |
242
+ | `SHUTDOWN_TIMEOUT_MS` | `30000` | Graceful shutdown timeout in milliseconds |
136
243
 
137
- This endpoint allows you to decrypt data in a single operation.
244
+ <p align="right"><a href="#contents">Back to Top</a></p>
138
245
 
139
- |Content-Type|Value|Description|
140
- |---|---|---|
141
- |passphrase|123456789abcdef|Passphrase to decrypt the message.|
142
- |message|{{data}}|Message to be decrypted.|
246
+ ## Examples
247
+
248
+ All examples are self-contained TypeScript files in the `examples/`
249
+ directory. Each uses `fetch` to call the server. Run any example
250
+ with:
251
+
252
+ ```bash
253
+ # Start the server in one terminal:
254
+ pnpm --filter @sebastienrousseau/crypto-server start
255
+
256
+ # Run an example in another:
257
+ npx ts-node examples/<name>.ts
258
+ ```
143
259
 
144
- ```shell
145
- curl --location --request GET 'http://localhost:3000/v1/decrypt' \
146
- --header 'passphrase: 123456789abcdef' \
147
- --header 'message: LS0tLS1CRUdJTiBQR1AgTUVTU0FHRS0tLS0tCgp3Y0ZNQXpMNWFTdVU0RWM4QVJBQWtnUUVEMVNwaTN5MmRrME1kbHQwYmtsMEdIWEoxbytxZHdzeWxZdlIKcjVycGVydXVmeWd3V0JTR1p6UHNSMG51MFg4SWxIQ0hYR2pha0N2WFVhMEZHTFNHR2pqRHdZQmViZjAvCitIVE51K1BMYzRvVmlvMXAwZEZraFFuOVVHSG82b1NVQmNqcmdsWTlsTW4ySzg3RVp2M1BUZ2k3aGtiMwpOWVhFazl5dWdLalVGU1RtMERDdGdpNkt2YUpycURpZStLbnJxSVNrckpxS0I0T1FuOUlNQk1UY3kxVEgKQld2QStyQ2llSFBNRHIrNFRwbTU5cFgxQUhCb0xPRm9WK1c1YlJoNEY5VHVxNzRaMW9pV2cyUFFEM252CjFtdnlZN1VIdEVuczBFbzYvWFRTQnZzNndQdFBJT2FoWGlTSC9UYmNod1RNTjlBZ1NSa3YzeEpWcGhjSgpPaGRGaFNMQ1dSUlR5UGxlUWpNeEoyemwwRm1JM2IrZnNYUkZlKzRCRjhiQjl6MUV4Nk9KOE1raG9yOFYKN3B5ZHR2UUVBVFlXMHVEc3pNb09UNHhqYnUvL29ESk45dnRINnBTY1hnQ3o2MGI4TTdHaXl6VGFoV3FLCmsvSklVWHJORjB2cjk3RWVnRGs3VXNFV3Y4MFhYdkg3dEtVTFNQcnRSTmxnbytqSjk5SzBmcm9iK1QxQwpIcVp4UzdpZCsxaTJOOHhQcUZnd2lDeHhXS1dMTGllQW1GRVVuQ3NXYUR0b05OZUhYbkJyLzk5b25PZGoKd0pWT0krQS9uZlU5bXh2ZGFnWlNqWnlMQ0ZDa1REQ05GeWxKL0dmUnZIWndBNGsya0ZqZXUvQWhQa0Y5Ck1EQktZdmNSWFJudklLOW5STHhIYjZKMUpoS3ppbnFpbHgrZmpQak9kdVRTd2NzQnlicThXenRPbmpscwp3WkZZVU9uQjdsQ0N4d3lxc3hqNlBQdkpLODFTOTBhaElQMkNUVVVsWWlMWTRSa05qRjlwNnArSXZoVW4KeFB3UXFwSU03V2ZpckZOM0tJT3QrOWpyazE3YStFVWtOelBuNm5jMHdobTUzWDFtaWhHOEJPYXc5UFgwCmlSWHZuTTlEL0dkWHI4ZTNhWDFRTnBXOVVlKzZ5c1NqZi85bEs5MVo5aTl4eUpmSW51eS9EdXpjSGtYawpTa1Z5VjRablE3MCsrY0JvN1JaYUkzZ3Zuak9HYkF2Z3dVakJIYUoyL0Vqd0oyd1FESm9lbkVYdUFEeTcKOHhLRWk2V2p3V1lBUXVlUmh1cGdhYmJIcVFGazltTWhHSGcvMlpkNkViMTYyTmVYeTU2RkYrK1lWSm5jCnJrSVN5bkFmdWJSc1hmZXUxYS9TWWJvR2h0cTNheWQ3VTM3YVpCUmtuclFieldxYituV2YvRk54YkRvRAprTkpsV1BDSHZBeHhNRTd3U2gxRkZQNmtCL24yVWxTV1JNUWZwY25hbzFFUW9QUGdQcWtDcm9vSXh4WVMKWEsySlEzOWtucmpmY053bEJZYlVkZnlNaVlSRi84cHJxT25YU242czJDTUN6WjAzamlNeEpYYmFDS0N6CnNqVXpmMDVMTnJ5V01nR0dmQWFRcWZhN3NYM3NtL3VjL09IV25paFpVaWsrVlZQbzNPVGE1NG0vRnd2YgpjQmxseFV6UHVYSzg3NG1lQVNPanRZc2luOUQzVnNIWVdHa0g5azJ6eFgyZEU1cTZUeGxUaU9FOWx0UHUKRWxmWXloU1dtMXJYVUxDZmprYkE2TjlSSEFMR0VNU0Uwa3p1QXpGZmh0OFlpVkhxcHZULytrWjF1azA3ClZLejhnS09UQllMNG84ZWt6V2ZJZ2N3MThkcmZ4SThIUHQ1cUtEZzJpUUM3M1BBS1gxaEJxVHp4LzJSbAptS2FBeFZ5NW1yanVwWmV3RnpMc2tiYlRhYWszd0Y2eHZVWktFNmFHdFRFcnZIVWJlL0xoL00zajVBQTQKUGRZQSs3djZMd3BTcGRVYTRQK2xKb0d0SVQremRQTXF2TE1Od3lyYk9nSWVveEZXZHNxQk9qM1kwNk0xCmhJUk9IamRnVG9yUUhvOD0KPTh4MUMKLS0tLS1FTkQgUEdQIE1FU1NBR0UtLS0tLQo='
260
+ | Category | Example | Purpose |
261
+ | :-------------- | :---------------------------------------------- | :--------------------------------------- |
262
+ | Algorithms | [algorithms.ts](examples/algorithms.ts) | List supported algorithms |
263
+ | Encryption | [encrypt.ts](examples/encrypt.ts) | Encrypt and decrypt via v2 endpoints |
264
+ | Hashing | [hash.ts](examples/hash.ts) | Hash data via POST /v2/hash |
265
+ | HMAC | [hmac.ts](examples/hmac.ts) | HMAC compute and verify |
266
+ | KDF | [kdf.ts](examples/kdf.ts) | Key derivation |
267
+ | Key Generation | [keygen.ts](examples/keygen.ts) | Generate keys via POST /v2/keys/generate |
268
+ | Key Wrap | [keywrap.ts](examples/keywrap.ts) | AES key wrapping and unwrapping |
269
+ | Passwords | [password.ts](examples/password.ts) | Password hash and verify |
270
+ | PW Encrypt | [pwencrypt.ts](examples/pwencrypt.ts) | Password-based encryption and decryption |
271
+ | PQ KEM | [pqkem.ts](examples/pqkem.ts) | Post-quantum KEM operations |
272
+ | PQ Sign | [pqsign.ts](examples/pqsign.ts) | Post-quantum ML-DSA signing |
273
+ | PQ Hash Sign | [pqhashsign.ts](examples/pqhashsign.ts) | Post-quantum SLH-DSA signing |
274
+ | Probes | [probes.ts](examples/probes.ts) | Health and readiness checks |
275
+ | Multi-Recipient | [multirecipient.ts](examples/multirecipient.ts) | Multi-recipient encryption |
276
+ | Sealed Box | [sealedbox.ts](examples/sealedbox.ts) | Sealed box operations |
277
+ | Secretbox | [secretbox.ts](examples/secretbox.ts) | Secretbox seal and open |
278
+ | Signing | [sign.ts](examples/sign.ts) | Sign and verify via v2 endpoints |
279
+
280
+ <p align="right"><a href="#contents">Back to Top</a></p>
281
+
282
+ <p align="right"><a href="#contents">Back to Top</a></p>
283
+
284
+ ---
285
+
286
+ ## Development
287
+
288
+ ```bash
289
+ pnpm --filter @sebastienrousseau/crypto-server run build
290
+ pnpm --filter @sebastienrousseau/crypto-server run test
291
+ pnpm --filter @sebastienrousseau/crypto-server run lint
292
+ pnpm --filter @sebastienrousseau/crypto-server run format
148
293
  ```
149
294
 
150
- ## Contributing to Crypto Server
295
+ All 18 packages in the Crypto Service workspace maintain a **100% coverage floor** across statements, branches, functions, and lines.
296
+
297
+ <p align="right"><a href="#contents">Back to Top</a></p>
298
+
299
+ ---
300
+
301
+ ## Security
302
+
303
+ Report vulnerabilities privately via [GitHub Security Advisories](https://github.com/sebastienrousseau/crypto-service/security/advisories) or according to [`SECURITY.md`](../../SECURITY.md). Never report security issues publicly.
304
+
305
+ Cryptographic operations use the `@noble/*` libraries, Node.js `crypto` and OpenPGP.js. `@noble/post-quantum` has not been independently audited and does not guarantee constant-time execution, and no module in this suite is FIPS 140-3 validated. Key zeroization is limited: JavaScript strings and garbage-collected buffers cannot be reliably wiped. See [`SECURITY.md`](../../SECURITY.md).
306
+
307
+ <p align="right"><a href="#contents">Back to Top</a></p>
308
+
309
+ ---
310
+
311
+ ## Documentation
312
+
313
+ - [Full Suite Documentation](https://sebastienrousseau.github.io/crypto-service/)
314
+ - [API Reference (TypeDoc)](https://sebastienrousseau.github.io/crypto-service/)
315
+ - [Developer Guide](../../DEVELOPMENT.md)
316
+ - [Security Policy](../../SECURITY.md)
317
+ - [Architecture & Design](../../ARCHITECTURE.md)
318
+
319
+ <p align="right"><a href="#contents">Back to Top</a></p>
320
+
321
+ ---
322
+
323
+ ## Stability guarantees
324
+
325
+ Versions advance strictly one step at a time on the `0.0.x` line (`v0.0.1` → `v0.0.2` → `v0.0.3` ... → `v0.0.999` → `v0.1.0`). Work for every release iteration begins on a dedicated `feat/v<version>` branch.
326
+
327
+ All 18 packages in the workspace move in lockstep. Public API signatures, cipher output formats, and serialization schemas are strictly versioned. Breaking changes to serialized formats or algorithm defaults are considered major breaking changes. Minimum toolchain upgrades (e.g. Node.js LTS floor) are governed by [POLICIES.md](../../docs/POLICIES.md).
328
+
329
+ <p align="right"><a href="#contents">Back to Top</a></p>
330
+
331
+ ---
151
332
 
152
- Contributions to Crypto Server are welcomed and encouraged! Please see our
153
- [Contributing Guidelines][1] for further details on the process for submitting
154
- pull requests to us.
333
+ ## License
155
334
 
156
- ## Appendix
335
+ Dual-licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0) or [MIT](https://opensource.org/licenses/MIT), at your option.
157
336
 
158
- *Elliptic curve for ECC keys: curve25519, p256, p384, p521, secp256k1,
159
- brainpoolP256r1,brainpoolP384r1, or brainpoolP512r1.*
337
+ Copyright (c) 2022-2026 Sebastien Rousseau and The Crypto Service Suite contributors.
160
338
 
161
- [1]: https://github.com/sebastienrousseau/crypto-server/blob/master/.github/CONTRIBUTING.md
162
- [2]: https://github.com/sebastienrousseau/crypto-service/tree/main/packages/crypto-lib
163
- [3]: https://www.fastify.io
164
- [4]: https://nodejs.org/en/
165
- [5]: https://www.npmjs.com/
166
- [6]: https://github.com
167
- [7]: https://github.com/sebastienrousseau/crypto-server
168
- [8]: https://github.com/sebastienrousseau/crypto-server/blob/main/LICENSE
169
- [9]: https://yarnpkg.com/getting-started
170
- [10]: https://pnpm.io/motivation
339
+ <p align="right"><a href="#contents">Back to Top</a></p>
@@ -1,21 +1,41 @@
1
- export declare type IQuerystring = {
2
- username: string;
3
- password: string;
4
- };
5
- export declare type IHeadersKeyBody = {
6
- type: string;
7
- bits: string;
1
+ export declare const KEY_TYPES: readonly ["ecc", "rsa"];
2
+ export type KeyType = (typeof KEY_TYPES)[number];
3
+ export declare const CURVE_TYPES: readonly ["curve25519", "ed25519", "p256", "p384", "p521", "secp256k1", "brainpoolP256r1", "brainpoolP384r1", "brainpoolP512r1"];
4
+ export type CurveType = (typeof CURVE_TYPES)[number];
5
+ export declare const FORMAT_TYPES: readonly ["armored", "binary", "object"];
6
+ export type FormatType = (typeof FORMAT_TYPES)[number];
7
+ export declare const REVOCATION_FLAGS: readonly [0, 1, 2, 3];
8
+ export type RevocationFlag = (typeof REVOCATION_FLAGS)[number];
9
+ export interface IBodyGenerate {
8
10
  name: string;
9
11
  email: string;
12
+ type: KeyType;
13
+ passphrase: string;
14
+ rsaBits?: number;
15
+ curve: CurveType;
16
+ keyExpirationTime?: number;
17
+ format: FormatType;
18
+ }
19
+ export interface IBodyEncrypt {
20
+ passphrase: string;
21
+ message: string;
22
+ publicKey: string;
23
+ privateKey?: string;
24
+ }
25
+ export interface IBodyDecrypt {
10
26
  passphrase: string;
11
- curve: string;
12
- expiration: string;
13
- format: string;
14
27
  message: string;
15
- sign: string;
16
- };
17
- export declare type IHeadersBody = {
28
+ publicKey: string;
29
+ privateKey: string;
30
+ }
31
+ export interface IBodyRevoke {
18
32
  passphrase: string;
33
+ flag: number;
34
+ reason: string;
35
+ }
36
+ export interface IBodyVerify {
37
+ date: string;
19
38
  message: string;
20
- };
39
+ verificationKeys: string;
40
+ }
21
41
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/@types/types.ts"],"names":[],"mappings":"AAAA,oBAAY,YAAY,GAAG;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,oBAAY,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,oBAAY,YAAY,GAAG;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/@types/types.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,SAAS,yBAA0B,CAAC;AAEjD,MAAM,MAAM,OAAO,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AAKjD,eAAO,MAAM,WAAW,kIAUd,CAAC;AAEX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAKrD,eAAO,MAAM,YAAY,0CAA2C,CAAC;AAErE,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAKvD,eAAO,MAAM,gBAAgB,uBAAwB,CAAC;AAEtD,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAiB/D,MAAM,WAAW,aAAa;IAE5B,IAAI,EAAE,MAAM,CAAC;IAEb,KAAK,EAAE,MAAM,CAAC;IAEd,IAAI,EAAE,OAAO,CAAC;IAEd,UAAU,EAAE,MAAM,CAAC;IAEnB,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,KAAK,EAAE,SAAS,CAAC;IAEjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B,MAAM,EAAE,UAAU,CAAC;CACpB;AAcD,MAAM,WAAW,YAAY;IAE3B,UAAU,EAAE,MAAM,CAAC;IAEnB,OAAO,EAAE,MAAM,CAAC;IAEhB,SAAS,EAAE,MAAM,CAAC;IAElB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAeD,MAAM,WAAW,YAAY;IAE3B,UAAU,EAAE,MAAM,CAAC;IAEnB,OAAO,EAAE,MAAM,CAAC;IAEhB,SAAS,EAAE,MAAM,CAAC;IAElB,UAAU,EAAE,MAAM,CAAC;CACpB;AAcD,MAAM,WAAW,WAAW;IAE1B,UAAU,EAAE,MAAM,CAAC;IAEnB,IAAI,EAAE,MAAM,CAAC;IAEb,MAAM,EAAE,MAAM,CAAC;CAChB;AAcD,MAAM,WAAW,WAAW;IAE1B,IAAI,EAAE,MAAM,CAAC;IAEb,OAAO,EAAE,MAAM,CAAC;IAEhB,gBAAgB,EAAE,MAAM,CAAC;CAC1B"}
@@ -1,3 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.REVOCATION_FLAGS = exports.FORMAT_TYPES = exports.CURVE_TYPES = exports.KEY_TYPES = void 0;
4
+ exports.KEY_TYPES = ["ecc", "rsa"];
5
+ exports.CURVE_TYPES = [
6
+ "curve25519",
7
+ "ed25519",
8
+ "p256",
9
+ "p384",
10
+ "p521",
11
+ "secp256k1",
12
+ "brainpoolP256r1",
13
+ "brainpoolP384r1",
14
+ "brainpoolP512r1",
15
+ ];
16
+ exports.FORMAT_TYPES = ["armored", "binary", "object"];
17
+ exports.REVOCATION_FLAGS = [0, 1, 2, 3];
3
18
  //# sourceMappingURL=types.js.map
@@ -0,0 +1,2 @@
1
+ export declare function authConfigError(env: NodeJS.ProcessEnv): string | null;
2
+ //# sourceMappingURL=auth-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-policy.d.ts","sourceRoot":"","sources":["../../src/config/auth-policy.ts"],"names":[],"mappings":"AAsBA,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,GAAG,IAAI,CAcrE"}
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.authConfigError = authConfigError;
4
+ const MIN_JWT_SECRET_BYTES = 32;
5
+ function authConfigError(env) {
6
+ const jwtSecret = env["JWT_SECRET"];
7
+ if (jwtSecret && Buffer.byteLength(jwtSecret) < MIN_JWT_SECRET_BYTES) {
8
+ return `JWT_SECRET must be at least ${MIN_JWT_SECRET_BYTES} bytes`;
9
+ }
10
+ const hasCredential = Boolean(env["CRYPTO_API_KEY"] || jwtSecret);
11
+ if (env["NODE_ENV"] === "production" &&
12
+ !hasCredential &&
13
+ env["ALLOW_ANONYMOUS"] !== "1") {
14
+ return "Production requires CRYPTO_API_KEY or JWT_SECRET (or ALLOW_ANONYMOUS=1 behind an authenticating gateway)";
15
+ }
16
+ return null;
17
+ }
18
+ //# sourceMappingURL=auth-policy.js.map