@catbee/utils 2.0.1 → 2.0.3

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.
package/crypto/index.cjs CHANGED
@@ -56,6 +56,287 @@ function md5(input) {
56
56
  return hash("md5", input);
57
57
  }
58
58
  __name(md5, "md5");
59
+ var DEFAULT_SIGNATURE_ENCODING = "base64url";
60
+ var subtle = globalThis.crypto?.subtle ?? crypto.webcrypto.subtle;
61
+ function getDigestLength(hash2) {
62
+ switch (hash2) {
63
+ case "SHA-256":
64
+ return 32;
65
+ case "SHA-384":
66
+ return 48;
67
+ case "SHA-512":
68
+ return 64;
69
+ default:
70
+ return 32;
71
+ }
72
+ }
73
+ __name(getDigestLength, "getDigestLength");
74
+ function resolveKeyAlgorithm({ type = "RSA-PSS", modulusLength = 2048, hash: hash2 = "SHA-256", namedCurve = "P-256" }) {
75
+ switch (type) {
76
+ case "RSA":
77
+ if (!Number.isInteger(modulusLength) || modulusLength < 2048) {
78
+ throw new Error("RSA modulusLength must be an integer greater than or equal to 2048");
79
+ }
80
+ return {
81
+ name: "RSASSA-PKCS1-v1_5",
82
+ modulusLength,
83
+ publicExponent: new Uint8Array([
84
+ 1,
85
+ 0,
86
+ 1
87
+ ]),
88
+ hash: hash2
89
+ };
90
+ case "RSA-PSS":
91
+ if (!Number.isInteger(modulusLength) || modulusLength < 2048) {
92
+ throw new Error("RSA-PSS modulusLength must be an integer greater than or equal to 2048");
93
+ }
94
+ return {
95
+ name: "RSA-PSS",
96
+ modulusLength,
97
+ publicExponent: new Uint8Array([
98
+ 1,
99
+ 0,
100
+ 1
101
+ ]),
102
+ hash: hash2
103
+ };
104
+ case "ECDSA":
105
+ return {
106
+ name: "ECDSA",
107
+ namedCurve
108
+ };
109
+ case "Ed25519":
110
+ return {
111
+ name: "Ed25519"
112
+ };
113
+ default:
114
+ throw new Error(`Unsupported key type: ${type}. Supported types: RSA, RSA-PSS, ECDSA, Ed25519`);
115
+ }
116
+ }
117
+ __name(resolveKeyAlgorithm, "resolveKeyAlgorithm");
118
+ function toBase64(buffer) {
119
+ if (typeof Buffer !== "undefined") {
120
+ return Buffer.from(buffer).toString("base64");
121
+ }
122
+ let binary = "";
123
+ const bytes = new Uint8Array(buffer);
124
+ const chunkSize = 32768;
125
+ for (let i = 0; i < bytes.length; i += chunkSize) {
126
+ binary += String.fromCharCode(...bytes.subarray(i, i + chunkSize));
127
+ }
128
+ return btoa(binary);
129
+ }
130
+ __name(toBase64, "toBase64");
131
+ function toPEM(base64, type, formatPemLines, addPrefixSuffix) {
132
+ const formattedBase64 = formatPemLines ? base64.match(/.{1,64}/g)?.join("\n") ?? base64 : base64;
133
+ if (!addPrefixSuffix) {
134
+ return formattedBase64;
135
+ }
136
+ const prefix = `-----BEGIN ${type}-----`;
137
+ const suffix = `-----END ${type}-----`;
138
+ return `${prefix}
139
+ ${formattedBase64}
140
+ ${suffix}`;
141
+ }
142
+ __name(toPEM, "toPEM");
143
+ function fromPEM(pem) {
144
+ const trimmedPem = pem.trim();
145
+ const format = trimmedPem.includes("BEGIN PRIVATE KEY") ? "pkcs8" : trimmedPem.includes("BEGIN PUBLIC KEY") ? "spki" : void 0;
146
+ if (!format) {
147
+ throw new Error("Unsupported PEM format. Expected PUBLIC KEY or PRIVATE KEY PEM block");
148
+ }
149
+ const base64 = trimmedPem.replace(/-----BEGIN [A-Z ]+-----/g, "").replace(/-----END [A-Z ]+-----/g, "").replace(/\s+/g, "");
150
+ return {
151
+ format,
152
+ binary: toArrayBuffer(Buffer.from(base64, "base64"))
153
+ };
154
+ }
155
+ __name(fromPEM, "fromPEM");
156
+ function toBinary(data, encoding = "utf8") {
157
+ if (typeof data === "string") {
158
+ return Uint8Array.from(Buffer.from(data, encoding));
159
+ }
160
+ if (Buffer.isBuffer(data)) {
161
+ return Uint8Array.from(data);
162
+ }
163
+ return data;
164
+ }
165
+ __name(toBinary, "toBinary");
166
+ function toArrayBuffer(data) {
167
+ const byteView = data instanceof Uint8Array ? data : Uint8Array.from(data);
168
+ const copy = new Uint8Array(byteView.byteLength);
169
+ copy.set(byteView);
170
+ return copy.buffer;
171
+ }
172
+ __name(toArrayBuffer, "toArrayBuffer");
173
+ function inferKeyTypeFromJwk(jwk, fallback) {
174
+ if (fallback) {
175
+ return fallback;
176
+ }
177
+ const keyType = typeof jwk.kty === "string" ? jwk.kty : void 0;
178
+ const curve = typeof jwk.crv === "string" ? jwk.crv : void 0;
179
+ const algorithm = typeof jwk.alg === "string" ? jwk.alg : void 0;
180
+ if (keyType === "OKP" && curve === "Ed25519") {
181
+ return "Ed25519";
182
+ }
183
+ if (keyType === "EC") {
184
+ return "ECDSA";
185
+ }
186
+ if (keyType === "RSA") {
187
+ return algorithm?.startsWith("PS") ? "RSA-PSS" : "RSA";
188
+ }
189
+ throw new Error("Unable to infer key type from JWK. Provide import options with an explicit type");
190
+ }
191
+ __name(inferKeyTypeFromJwk, "inferKeyTypeFromJwk");
192
+ function resolveDefaultUsages(format, usages) {
193
+ return usages ?? (format === "pkcs8" ? [
194
+ "sign"
195
+ ] : [
196
+ "verify"
197
+ ]);
198
+ }
199
+ __name(resolveDefaultUsages, "resolveDefaultUsages");
200
+ function inferJwkUsages(jwk, usages) {
201
+ if (usages) {
202
+ return usages;
203
+ }
204
+ if (Array.isArray(jwk.key_ops)) {
205
+ const inferredFromKeyOps = jwk.key_ops.filter((usage) => usage === "sign" || usage === "verify");
206
+ if (inferredFromKeyOps.length === 0) {
207
+ throw new Error("JWK key_ops must include at least one of sign or verify when provided");
208
+ }
209
+ return inferredFromKeyOps;
210
+ }
211
+ if (typeof jwk.d === "string" && jwk.d.length > 0) {
212
+ return [
213
+ "sign"
214
+ ];
215
+ }
216
+ return [
217
+ "verify"
218
+ ];
219
+ }
220
+ __name(inferJwkUsages, "inferJwkUsages");
221
+ function resolveSignAlgorithm(key, options = {}) {
222
+ const hash2 = options.hash ?? "SHA-256";
223
+ switch (key.algorithm.name) {
224
+ case "RSASSA-PKCS1-v1_5":
225
+ return "RSASSA-PKCS1-v1_5";
226
+ case "RSA-PSS": {
227
+ const keyAlgorithm = key.algorithm;
228
+ const pssHash = options.hash ?? keyAlgorithm.hash.name;
229
+ return {
230
+ name: "RSA-PSS",
231
+ saltLength: options.saltLength ?? getDigestLength(pssHash)
232
+ };
233
+ }
234
+ case "ECDSA":
235
+ return {
236
+ name: "ECDSA",
237
+ hash: hash2
238
+ };
239
+ case "Ed25519":
240
+ return "Ed25519";
241
+ default:
242
+ throw new Error(`Unsupported signing key algorithm: ${key.algorithm.name}`);
243
+ }
244
+ }
245
+ __name(resolveSignAlgorithm, "resolveSignAlgorithm");
246
+ function arrayBufferToBuffer(buffer) {
247
+ return Buffer.from(buffer);
248
+ }
249
+ __name(arrayBufferToBuffer, "arrayBufferToBuffer");
250
+ async function generateKeys(options = {}) {
251
+ const { type = "RSA-PSS", modulusLength = 2048, hash: hash2 = "SHA-256", namedCurve = "P-256", extractable = false, includeCryptoKeys = false, formatPemLines = true, addPrefixSuffix = true } = options;
252
+ const algorithm = resolveKeyAlgorithm({
253
+ type,
254
+ modulusLength,
255
+ hash: hash2,
256
+ namedCurve
257
+ });
258
+ const usages = [
259
+ "sign",
260
+ "verify"
261
+ ];
262
+ const keyPair = await subtle.generateKey(algorithm, extractable, usages);
263
+ const [publicKeyBuf, privateKeyBuf] = await Promise.all([
264
+ subtle.exportKey("spki", keyPair.publicKey),
265
+ extractable ? subtle.exportKey("pkcs8", keyPair.privateKey) : Promise.resolve(void 0)
266
+ ]);
267
+ const publicKeyBase64 = toBase64(publicKeyBuf);
268
+ const privateKeyBase64 = privateKeyBuf ? toBase64(privateKeyBuf) : void 0;
269
+ const result = {
270
+ type,
271
+ publicKey: toPEM(publicKeyBase64, "PUBLIC KEY", formatPemLines, addPrefixSuffix),
272
+ publicKeyBuffer: publicKeyBuf
273
+ };
274
+ if (privateKeyBase64 && privateKeyBuf) {
275
+ result.privateKey = toPEM(privateKeyBase64, "PRIVATE KEY", formatPemLines, addPrefixSuffix);
276
+ result.privateKeyBuffer = privateKeyBuf;
277
+ }
278
+ if (includeCryptoKeys) {
279
+ result.privateKeyCrypto = keyPair.privateKey;
280
+ result.publicKeyCrypto = keyPair.publicKey;
281
+ }
282
+ return result;
283
+ }
284
+ __name(generateKeys, "generateKeys");
285
+ async function sign(data, privateKeyCrypto, options = {}) {
286
+ const algorithm = resolveSignAlgorithm(privateKeyCrypto, options);
287
+ const signature = await subtle.sign(algorithm, privateKeyCrypto, toArrayBuffer(toBinary(data, options.inputEncoding)));
288
+ return arrayBufferToBuffer(signature).toString(options.outputEncoding ?? DEFAULT_SIGNATURE_ENCODING);
289
+ }
290
+ __name(sign, "sign");
291
+ async function verify(data, signature, publicKeyCrypto, options = {}) {
292
+ const algorithm = resolveSignAlgorithm(publicKeyCrypto, options);
293
+ const signatureBytes = typeof signature === "string" ? Uint8Array.from(Buffer.from(signature, options.signatureEncoding ?? DEFAULT_SIGNATURE_ENCODING)) : toBinary(signature);
294
+ return subtle.verify(algorithm, publicKeyCrypto, toArrayBuffer(signatureBytes), toArrayBuffer(toBinary(data, options.inputEncoding)));
295
+ }
296
+ __name(verify, "verify");
297
+ async function importKey(key, options = {}) {
298
+ const extractable = options.extractable ?? false;
299
+ if (typeof key === "string") {
300
+ if (!options.type) {
301
+ throw new Error("Key type is required when importing PEM keys");
302
+ }
303
+ const { format, binary } = fromPEM(key);
304
+ const algorithm2 = resolveKeyAlgorithm({
305
+ type: options.type,
306
+ hash: options.hash,
307
+ namedCurve: options.namedCurve
308
+ });
309
+ return subtle.importKey(format, binary, algorithm2, extractable, resolveDefaultUsages(format, options.usages));
310
+ }
311
+ const keyType = inferKeyTypeFromJwk(key, options.type);
312
+ const algorithm = resolveKeyAlgorithm({
313
+ type: keyType,
314
+ hash: options.hash,
315
+ namedCurve: options.namedCurve
316
+ });
317
+ return subtle.importKey("jwk", key, algorithm, extractable, inferJwkUsages(key, options.usages));
318
+ }
319
+ __name(importKey, "importKey");
320
+ async function exportKey(key, format = "jwk", options = {}) {
321
+ if (format === "jwk") {
322
+ return subtle.exportKey("jwk", key);
323
+ }
324
+ const binary = key.type === "private" ? await subtle.exportKey("pkcs8", key) : await subtle.exportKey("spki", key);
325
+ return toPEM(toBase64(binary), key.type === "private" ? "PRIVATE KEY" : "PUBLIC KEY", options.formatPemLines ?? true, options.addPrefixSuffix ?? true);
326
+ }
327
+ __name(exportKey, "exportKey");
328
+ async function fingerprint(publicKey, encoding = "base64url") {
329
+ if (publicKey.type !== "public") {
330
+ throw new Error("fingerprint requires a public key");
331
+ }
332
+ const spki = await subtle.exportKey("spki", publicKey);
333
+ return crypto.createHash("sha256").update(arrayBufferToBuffer(spki)).digest(encoding);
334
+ }
335
+ __name(fingerprint, "fingerprint");
336
+ async function getKeyId(publicKey) {
337
+ return fingerprint(publicKey, "base64url");
338
+ }
339
+ __name(getKeyId, "getKeyId");
59
340
  function randomString() {
60
341
  return sha256(id.uuid());
61
342
  }
@@ -213,13 +494,18 @@ __name(verifyPassword, "verifyPassword");
213
494
  exports.createSignedToken = createSignedToken;
214
495
  exports.decrypt = decrypt;
215
496
  exports.encrypt = encrypt;
497
+ exports.exportKey = exportKey;
498
+ exports.fingerprint = fingerprint;
216
499
  exports.generateApiKey = generateApiKey;
500
+ exports.generateKeys = generateKeys;
217
501
  exports.generateNonce = generateNonce;
218
502
  exports.generateRandomBytes = generateRandomBytes;
219
503
  exports.generateRandomBytesAsString = generateRandomBytesAsString;
504
+ exports.getKeyId = getKeyId;
220
505
  exports.hash = hash;
221
506
  exports.hashPassword = hashPassword;
222
507
  exports.hmac = hmac;
508
+ exports.importKey = importKey;
223
509
  exports.md5 = md5;
224
510
  exports.pbkdf2Hash = pbkdf2Hash;
225
511
  exports.randomString = randomString;
@@ -228,5 +514,7 @@ exports.secureRandomInt = secureRandomInt;
228
514
  exports.sha1 = sha1;
229
515
  exports.sha256 = sha256;
230
516
  exports.sha256Hmac = sha256Hmac;
517
+ exports.sign = sign;
518
+ exports.verify = verify;
231
519
  exports.verifyPassword = verifyPassword;
232
520
  exports.verifySignedToken = verifySignedToken;
package/crypto/index.d.ts CHANGED
@@ -22,7 +22,7 @@
22
22
  * SOFTWARE.
23
23
  */
24
24
 
25
- import { BinaryToTextEncoding, CipherGCMTypes } from 'node:crypto';
25
+ import { CipherGCMTypes, BinaryToTextEncoding } from 'node:crypto';
26
26
 
27
27
  type BufferEncoding = 'ascii' | 'utf8' | 'utf-8' | 'utf16le' | 'utf-16le' | 'ucs2' | 'ucs-2' | 'base64' | 'base64url' | 'latin1' | 'binary' | 'hex';
28
28
  /**
@@ -75,6 +75,233 @@ declare function sha256(input: string, encoding?: BinaryToTextEncoding): string;
75
75
  * @returns {string} MD5 hash as a string.
76
76
  */
77
77
  declare function md5(input: string): string;
78
+ /**
79
+ * Supported asymmetric key types for generation.
80
+ *
81
+ * - `RSA` → RSASSA-PKCS1-v1_5 (legacy compatibility)
82
+ * - `RSA-PSS` → Recommended RSA variant with modern padding
83
+ * - `ECDSA` → Elliptic Curve (fast, smaller keys)
84
+ * - `Ed25519` → Modern, simple, highly secure (recommended)
85
+ */
86
+ type EncKeyType = 'RSA' | 'RSA-PSS' | 'ECDSA' | 'Ed25519';
87
+ /**
88
+ * Options to configure key pair generation.
89
+ */
90
+ interface GenerateKeyOptions {
91
+ /**
92
+ * Type of key algorithm to generate.
93
+ * @default 'RSA-PSS'
94
+ */
95
+ type?: EncKeyType;
96
+ /**
97
+ * RSA modulus length in bits.
98
+ * Recommended: 2048 or 3072 (4096 for high security).
99
+ * @default 2048
100
+ */
101
+ modulusLength?: number;
102
+ /**
103
+ * Hash algorithm used for signing.
104
+ *
105
+ * ⚠️ For ECDSA, hash is used during sign/verify, not key generation.
106
+ * @default 'SHA-256'
107
+ */
108
+ hash?: 'SHA-256' | 'SHA-384' | 'SHA-512';
109
+ /**
110
+ * Named curve for ECDSA keys.
111
+ * @default 'P-256'
112
+ */
113
+ namedCurve?: 'P-256' | 'P-384' | 'P-521';
114
+ /**
115
+ * Whether the private key can be exported.
116
+ *
117
+ * ⚠️ Set to `false` in production if you don't need to export keys.
118
+ * @default false
119
+ */
120
+ extractable?: boolean;
121
+ /**
122
+ * Whether to include generated CryptoKey objects in the result.
123
+ *
124
+ * Useful when private key export is disabled (`extractable: false`) but
125
+ * you still want to sign/verify with the in-memory keys.
126
+ * @default false
127
+ */
128
+ includeCryptoKeys?: boolean;
129
+ /**
130
+ * Whether to format Base64 output into 64-character lines (PEM style).
131
+ * @default true
132
+ */
133
+ formatPemLines?: boolean;
134
+ /**
135
+ * Whether to include PEM prefix/suffix headers.
136
+ *
137
+ * Example:
138
+ * -----BEGIN PRIVATE KEY-----
139
+ * -----END PRIVATE KEY-----
140
+ *
141
+ * @default true
142
+ */
143
+ addPrefixSuffix?: boolean;
144
+ }
145
+ /**
146
+ * Result object returned from {@link generateKeys}
147
+ */
148
+ interface GenerateKeyResult {
149
+ /** Algorithm type used */
150
+ type: EncKeyType;
151
+ /** PEM or Base64 encoded private key (only when extractable is true) */
152
+ privateKey?: string;
153
+ /** PEM or Base64 encoded public key */
154
+ publicKey: string;
155
+ /** Raw PKCS8 private key buffer (only when extractable is true) */
156
+ privateKeyBuffer?: ArrayBuffer;
157
+ /** Raw SPKI public key buffer */
158
+ publicKeyBuffer: ArrayBuffer;
159
+ /** Optional generated private CryptoKey */
160
+ privateKeyCrypto?: CryptoKey;
161
+ /** Optional generated public CryptoKey */
162
+ publicKeyCrypto?: CryptoKey;
163
+ }
164
+ type SupportedAlgorithm = RsaHashedKeyGenParams | EcKeyGenParams | {
165
+ name: 'Ed25519';
166
+ };
167
+ type SignatureEncoding = 'base64' | 'base64url' | 'hex';
168
+ interface SignatureOptions {
169
+ /**
170
+ * Hash algorithm used for ECDSA signatures.
171
+ *
172
+ * ⚠️ For ECDSA, hash is used during sign/verify, not key generation.
173
+ * @default 'SHA-256'
174
+ */
175
+ hash?: 'SHA-256' | 'SHA-384' | 'SHA-512';
176
+ /**
177
+ * Salt length for RSA-PSS signatures.
178
+ * Defaults to the digest length of the configured hash.
179
+ */
180
+ saltLength?: number;
181
+ /**
182
+ * Output encoding for generated signatures.
183
+ * @default 'base64url'
184
+ */
185
+ outputEncoding?: SignatureEncoding;
186
+ /**
187
+ * Input encoding when the payload is a string.
188
+ * @default 'utf8'
189
+ */
190
+ inputEncoding?: BufferEncoding;
191
+ }
192
+ interface VerifyOptions extends Omit<SignatureOptions, 'outputEncoding'> {
193
+ /**
194
+ * Encoding of the provided signature when it is a string.
195
+ * @default 'base64url'
196
+ */
197
+ signatureEncoding?: SignatureEncoding;
198
+ }
199
+ interface ImportKeyOptions {
200
+ /**
201
+ * Explicit key type. Required for PEM import when the algorithm cannot be inferred.
202
+ */
203
+ type?: EncKeyType;
204
+ /**
205
+ * Hash algorithm used with RSA and ECDSA operations.
206
+ *
207
+ * ⚠️ For ECDSA, hash is used during sign/verify, not key generation.
208
+ * @default 'SHA-256'
209
+ */
210
+ hash?: 'SHA-256' | 'SHA-384' | 'SHA-512';
211
+ /**
212
+ * Named curve for ECDSA keys.
213
+ * @default 'P-256'
214
+ */
215
+ namedCurve?: 'P-256' | 'P-384' | 'P-521';
216
+ /**
217
+ * Whether the imported key can be exported.
218
+ * @default false
219
+ */
220
+ extractable?: boolean;
221
+ /**
222
+ * Allowed operations for the imported key.
223
+ * Defaults to `['sign']` for private keys and `['verify']` for public keys.
224
+ */
225
+ usages?: Array<'sign' | 'verify'>;
226
+ }
227
+ interface ExportKeyOptions {
228
+ /**
229
+ * Whether to format Base64 output into 64-character lines (PEM style).
230
+ * @default true
231
+ */
232
+ formatPemLines?: boolean;
233
+ /**
234
+ * Whether to include PEM prefix/suffix headers.
235
+ * @default true
236
+ */
237
+ addPrefixSuffix?: boolean;
238
+ }
239
+ /**
240
+ * Generates an asymmetric cryptographic key pair using Web Crypto API.
241
+ *
242
+ * Supports RSA, RSA-PSS, ECDSA, and Ed25519.
243
+ *
244
+ * @param options - Configuration for key generation
245
+ *
246
+ * @returns Promise resolving to generated key pair (PEM + raw buffers)
247
+ *
248
+ * @example
249
+ * ```ts
250
+ * const keys = await generateKeys({
251
+ * type: 'RSA-PSS',
252
+ * modulusLength: 2048
253
+ * });
254
+ *
255
+ * console.log(keys.publicKey);
256
+ * ```
257
+ *
258
+ * @example
259
+ * ```ts
260
+ * const keys = await generateKeys({
261
+ * type: 'Ed25519',
262
+ * extractable: false
263
+ * });
264
+ * ```
265
+ *
266
+ * @remarks
267
+ * - Uses `crypto.subtle.generateKey`
268
+ * - Private key is exported in PKCS#8 format
269
+ * - Public key is exported in SPKI format
270
+ * - Ed25519 requires modern runtime support (Node 18+, modern browsers)
271
+ *
272
+ * ⚠️ Security Notes:
273
+ * - Avoid logging private keys in production
274
+ * - Prefer `extractable: false` when possible
275
+ * - Store keys securely (e.g., KMS, HSM)
276
+ */
277
+ declare function generateKeys(options?: GenerateKeyOptions): Promise<GenerateKeyResult>;
278
+ /**
279
+ * Signs data with a private key generated or imported through Web Crypto.
280
+ * ⚠️ ECDSA signatures are DER-encoded.
281
+ * Some systems (e.g., JWT ES256, blockchain) require raw (r || s) format.
282
+ * Conversion may be required depending on the consumer.
283
+ */
284
+ declare function sign(data: string | Buffer | Uint8Array, privateKeyCrypto: CryptoKey, options?: SignatureOptions): Promise<string>;
285
+ /**
286
+ * Verifies a signature with a public key generated or imported through Web Crypto.
287
+ */
288
+ declare function verify(data: string | Buffer | Uint8Array, signature: string | Buffer | Uint8Array, publicKeyCrypto: CryptoKey, options?: VerifyOptions): Promise<boolean>;
289
+ /**
290
+ * Imports a PEM or JWK asymmetric key into Web Crypto.
291
+ */
292
+ declare function importKey(key: string | JsonWebKey, options?: ImportKeyOptions): Promise<CryptoKey>;
293
+ /**
294
+ * Exports an asymmetric CryptoKey as JWK or PEM.
295
+ */
296
+ declare function exportKey(key: CryptoKey, format?: 'jwk' | 'pem', options?: ExportKeyOptions): Promise<JsonWebKey | string>;
297
+ /**
298
+ * Produces a stable SHA-256 fingerprint for a public key.
299
+ */
300
+ declare function fingerprint(publicKey: CryptoKey, encoding?: SignatureEncoding): Promise<string>;
301
+ /**
302
+ * Generates a unique identifier for a public key by computing its fingerprint.
303
+ */
304
+ declare function getKeyId(publicKey: CryptoKey): Promise<string>;
78
305
  /**
79
306
  * Generates a cryptographically strong random string by hashing a random UUID with SHA-256.
80
307
  *
@@ -244,5 +471,5 @@ declare function hashPassword(password: string, saltLength?: number, keyLength?:
244
471
  */
245
472
  declare function verifyPassword(password: string, hash: string): Promise<boolean>;
246
473
 
247
- export { createSignedToken, decrypt, encrypt, generateApiKey, generateNonce, generateRandomBytes, generateRandomBytesAsString, hash, hashPassword, hmac, md5, pbkdf2Hash, randomString, safeCompare, secureRandomInt, sha1, sha256, sha256Hmac, verifyPassword, verifySignedToken };
248
- export type { BufferEncoding, DecryptionOptions, EncryptionOptions, EncryptionResult };
474
+ export { createSignedToken, decrypt, encrypt, exportKey, fingerprint, generateApiKey, generateKeys, generateNonce, generateRandomBytes, generateRandomBytesAsString, getKeyId, hash, hashPassword, hmac, importKey, md5, pbkdf2Hash, randomString, safeCompare, secureRandomInt, sha1, sha256, sha256Hmac, sign, verify, verifyPassword, verifySignedToken };
475
+ export type { BufferEncoding, DecryptionOptions, EncKeyType, EncryptionOptions, EncryptionResult, ExportKeyOptions, GenerateKeyOptions, GenerateKeyResult, ImportKeyOptions, SignatureEncoding, SignatureOptions, SupportedAlgorithm, VerifyOptions };