@lakutata/security 3.0.0-beta.0
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/LICENSE +23 -0
- package/README.md +143 -0
- package/THIRD_PARTY_NOTICES.md +36 -0
- package/dist/cjs/exceptions/DecryptionFailedException.d.ts +13 -0
- package/dist/cjs/exceptions/DecryptionFailedException.js +20 -0
- package/dist/cjs/exceptions/InvalidSignatureException.d.ts +13 -0
- package/dist/cjs/exceptions/InvalidSignatureException.js +20 -0
- package/dist/cjs/exceptions/PasswordTooLongException.d.ts +12 -0
- package/dist/cjs/exceptions/PasswordTooLongException.js +19 -0
- package/dist/cjs/exports/Security.d.ts +19 -0
- package/dist/cjs/exports/Security.js +38 -0
- package/dist/cjs/functions/Encryption.d.ts +95 -0
- package/dist/cjs/functions/Encryption.js +208 -0
- package/dist/cjs/functions/GenerateSecret.d.ts +20 -0
- package/dist/cjs/functions/GenerateSecret.js +26 -0
- package/dist/cjs/functions/HMAC.d.ts +50 -0
- package/dist/cjs/functions/HMAC.js +58 -0
- package/dist/cjs/functions/TimingSafeEqual.d.ts +18 -0
- package/dist/cjs/functions/TimingSafeEqual.js +30 -0
- package/dist/cjs/lib/AssertKey.d.ts +5 -0
- package/dist/cjs/lib/AssertKey.js +11 -0
- package/dist/cjs/lib/bcrypt/constants.d.ts +13 -0
- package/dist/cjs/lib/bcrypt/constants.js +213 -0
- package/dist/cjs/lib/bcrypt/index.d.ts +84 -0
- package/dist/cjs/lib/bcrypt/index.js +658 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/providers/Crypt.d.ts +71 -0
- package/dist/cjs/providers/Crypt.js +88 -0
- package/dist/cjs/providers/Mac.d.ts +86 -0
- package/dist/cjs/providers/Mac.js +114 -0
- package/dist/cjs/providers/PasswordHash.d.ts +78 -0
- package/dist/cjs/providers/PasswordHash.js +146 -0
- package/dist/esm/exceptions/DecryptionFailedException.js +16 -0
- package/dist/esm/exceptions/InvalidSignatureException.js +16 -0
- package/dist/esm/exceptions/PasswordTooLongException.js +15 -0
- package/dist/esm/exports/Security.js +19 -0
- package/dist/esm/functions/Encryption.js +202 -0
- package/dist/esm/functions/GenerateSecret.js +23 -0
- package/dist/esm/functions/HMAC.js +54 -0
- package/dist/esm/functions/TimingSafeEqual.js +27 -0
- package/dist/esm/lib/AssertKey.js +8 -0
- package/dist/esm/lib/bcrypt/constants.js +202 -0
- package/dist/esm/lib/bcrypt/index.js +645 -0
- package/dist/esm/providers/Crypt.js +84 -0
- package/dist/esm/providers/Mac.js +110 -0
- package/dist/esm/providers/PasswordHash.js +109 -0
- package/dist/types/exceptions/DecryptionFailedException.d.ts +13 -0
- package/dist/types/exceptions/InvalidSignatureException.d.ts +13 -0
- package/dist/types/exceptions/PasswordTooLongException.d.ts +12 -0
- package/dist/types/exports/Security.d.ts +19 -0
- package/dist/types/functions/Encryption.d.ts +95 -0
- package/dist/types/functions/GenerateSecret.d.ts +20 -0
- package/dist/types/functions/HMAC.d.ts +50 -0
- package/dist/types/functions/TimingSafeEqual.d.ts +18 -0
- package/dist/types/lib/AssertKey.d.ts +5 -0
- package/dist/types/lib/bcrypt/constants.d.ts +13 -0
- package/dist/types/lib/bcrypt/index.d.ts +84 -0
- package/dist/types/providers/Crypt.d.ts +71 -0
- package/dist/types/providers/Mac.d.ts +86 -0
- package/dist/types/providers/PasswordHash.d.ts +78 -0
- package/package.json +45 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { createCipheriv, createDecipheriv, hkdfSync, randomBytes, scrypt as scryptCallback } from 'node:crypto';
|
|
2
|
+
import { DecryptionFailedException } from '../exceptions/DecryptionFailedException.js';
|
|
3
|
+
import { assertKey } from '../lib/AssertKey.js';
|
|
4
|
+
/**
|
|
5
|
+
* The versions of the encrypted data: the key derivation (the cipher is AES-256-GCM)
|
|
6
|
+
*/
|
|
7
|
+
const KEY_VERSION = 1;
|
|
8
|
+
const PASSWORD_VERSION = 2;
|
|
9
|
+
const SALT_LENGTH = 16;
|
|
10
|
+
const IV_LENGTH = 12;
|
|
11
|
+
const TAG_LENGTH = 16;
|
|
12
|
+
const HEADER_LENGTH = 1 + SALT_LENGTH + IV_LENGTH;
|
|
13
|
+
const KEY_LENGTH = 32;
|
|
14
|
+
/**
|
|
15
|
+
* The scrypt parameters of the password version (about 16 MB and a few tens of milliseconds)
|
|
16
|
+
*/
|
|
17
|
+
const SCRYPT_OPTIONS = { N: 16384, r: 8, p: 1 };
|
|
18
|
+
/**
|
|
19
|
+
* The key of a message: derived from the key with the salt of the message (HKDF-sha256)
|
|
20
|
+
* @param key
|
|
21
|
+
* @param salt
|
|
22
|
+
*/
|
|
23
|
+
function deriveKey(key, salt) {
|
|
24
|
+
return Buffer.from(hkdfSync('sha256', key, salt, 'lakutata-encryption', KEY_LENGTH));
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The key of a message: derived from the password with the salt of the message (scrypt)
|
|
28
|
+
* @param password
|
|
29
|
+
* @param salt
|
|
30
|
+
*/
|
|
31
|
+
function derivePasswordKey(password, salt) {
|
|
32
|
+
return new Promise((resolve, reject) => scryptCallback(password, salt, KEY_LENGTH, SCRYPT_OPTIONS, (error, key) => error ? reject(error) : resolve(key)));
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Encrypt with a key: version, salt, iv, tag and ciphertext, base64url encoded
|
|
36
|
+
* @param version
|
|
37
|
+
* @param salt
|
|
38
|
+
* @param key
|
|
39
|
+
* @param data
|
|
40
|
+
*/
|
|
41
|
+
function seal(version, salt, key, data) {
|
|
42
|
+
const iv = randomBytes(IV_LENGTH);
|
|
43
|
+
const header = Buffer.concat([Buffer.from([version]), salt, iv]);
|
|
44
|
+
const cipher = createCipheriv('aes-256-gcm', key, iv);
|
|
45
|
+
//The header is authenticated too
|
|
46
|
+
cipher.setAAD(header);
|
|
47
|
+
const ciphertext = Buffer.concat([cipher.update(data), cipher.final()]);
|
|
48
|
+
return Buffer.concat([header, cipher.getAuthTag(), ciphertext]).toString('base64url');
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The parts of encrypted data (undefined: not encrypted data of the version)
|
|
52
|
+
* @param encrypted
|
|
53
|
+
* @param version
|
|
54
|
+
*/
|
|
55
|
+
function parts(encrypted, version) {
|
|
56
|
+
const buffer = Buffer.from(encrypted, 'base64url');
|
|
57
|
+
if (buffer.length < HEADER_LENGTH + TAG_LENGTH || buffer[0] !== version)
|
|
58
|
+
return undefined;
|
|
59
|
+
return {
|
|
60
|
+
header: buffer.subarray(0, HEADER_LENGTH),
|
|
61
|
+
salt: buffer.subarray(1, 1 + SALT_LENGTH),
|
|
62
|
+
iv: buffer.subarray(1 + SALT_LENGTH, HEADER_LENGTH),
|
|
63
|
+
tag: buffer.subarray(HEADER_LENGTH, HEADER_LENGTH + TAG_LENGTH),
|
|
64
|
+
ciphertext: buffer.subarray(HEADER_LENGTH + TAG_LENGTH)
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Decrypt the parts with a key (undefined: the key does not decrypt them, or they were changed)
|
|
69
|
+
* @param part
|
|
70
|
+
* @param key
|
|
71
|
+
*/
|
|
72
|
+
function open(part, key) {
|
|
73
|
+
try {
|
|
74
|
+
const decipher = createDecipheriv('aes-256-gcm', key, part.iv);
|
|
75
|
+
decipher.setAAD(part.header);
|
|
76
|
+
decipher.setAuthTag(part.tag);
|
|
77
|
+
return Buffer.concat([decipher.update(part.ciphertext), decipher.final()]);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Encrypt data with a secret key, using AES-256-GCM (authenticated encryption): the output is confidential and
|
|
85
|
+
* tamper-proof. Each call derives a fresh key from the key and a random 16-byte salt (HKDF-sha256) and uses a random
|
|
86
|
+
* 12-byte IV, so encrypting the same data twice gives different outputs. The {@link Crypt} provider does the same with
|
|
87
|
+
* configured keys and key rotation.
|
|
88
|
+
*
|
|
89
|
+
* The key must be random (see {@link generateSecret}): its derivation is fast, so a password used as a key is open to
|
|
90
|
+
* brute force; use {@link encryptByPassword} for passwords. The function refuses an empty key, but does not check
|
|
91
|
+
* the key's length or strength otherwise.
|
|
92
|
+
* @param data The data to encrypt: a string (encrypted as its UTF-8 bytes) or bytes.
|
|
93
|
+
* @param key The secret key: a string (used as its UTF-8 bytes, not decoded from base64) or bytes, not empty; 32
|
|
94
|
+
* random bytes recommended.
|
|
95
|
+
* @returns The encrypted data, base64url encoded without padding: 1 version byte, the salt, the IV, a 16-byte
|
|
96
|
+
* authentication tag and the ciphertext (45 bytes more than the data, before base64url).
|
|
97
|
+
* @throws {RangeError} When the key is empty.
|
|
98
|
+
* @example
|
|
99
|
+
* ```typescript
|
|
100
|
+
* import {decryptByKey, encryptByKey, generateSecret} from 'lakutata/security'
|
|
101
|
+
*
|
|
102
|
+
* const key: string = process.env.CRYPT_KEY ?? generateSecret()
|
|
103
|
+
* const encrypted: string = encryptByKey('card ending 4242', key)
|
|
104
|
+
* console.log(decryptByKey(encrypted, key).toString('utf8'))
|
|
105
|
+
* ```
|
|
106
|
+
*/
|
|
107
|
+
export function encryptByKey(data, key) {
|
|
108
|
+
assertKey(key);
|
|
109
|
+
const salt = randomBytes(SALT_LENGTH);
|
|
110
|
+
return seal(KEY_VERSION, salt, deriveKey(key, salt), data);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Decrypt data encrypted by {@link encryptByKey} (or {@link Crypt.encrypt}) with one of the keys, tried in order: list
|
|
114
|
+
* the current key and the previous ones during a key rotation. The authentication tag is checked before anything is
|
|
115
|
+
* returned, so changed data is never decrypted.
|
|
116
|
+
* @param encrypted The encrypted data, base64url as {@link encryptByKey} returns it.
|
|
117
|
+
* @param keys The key, or the keys to try: strings (used as their UTF-8 bytes) or bytes, none empty.
|
|
118
|
+
* @returns The decrypted bytes (call `.toString('utf8')` for a string).
|
|
119
|
+
* @throws {DecryptionFailedException} When no key decrypts the data, or it was changed, truncated or not produced by
|
|
120
|
+
* {@link encryptByKey} (data encrypted by {@link encryptByPassword} included).
|
|
121
|
+
* @throws {RangeError} When a key is empty.
|
|
122
|
+
* @example
|
|
123
|
+
* ```typescript
|
|
124
|
+
* import {decryptByKey, DecryptionFailedException} from 'lakutata/security'
|
|
125
|
+
*
|
|
126
|
+
* declare const encrypted: string
|
|
127
|
+
* declare const currentKey: string
|
|
128
|
+
* declare const previousKey: string
|
|
129
|
+
*
|
|
130
|
+
* try {
|
|
131
|
+
* //The new key first, the previous one while old data remains
|
|
132
|
+
* const secret: string = decryptByKey(encrypted, [currentKey, previousKey]).toString('utf8')
|
|
133
|
+
* console.log(secret)
|
|
134
|
+
* } catch (error) {
|
|
135
|
+
* if (error instanceof DecryptionFailedException) console.log('Changed, or encrypted with an unknown key')
|
|
136
|
+
* }
|
|
137
|
+
* ```
|
|
138
|
+
*/
|
|
139
|
+
export function decryptByKey(encrypted, keys) {
|
|
140
|
+
const candidates = Array.isArray(keys) ? keys : [keys];
|
|
141
|
+
candidates.forEach(assertKey);
|
|
142
|
+
const part = parts(encrypted, KEY_VERSION);
|
|
143
|
+
if (part) {
|
|
144
|
+
for (const key of candidates) {
|
|
145
|
+
const decrypted = open(part, deriveKey(key, part.salt));
|
|
146
|
+
if (decrypted)
|
|
147
|
+
return decrypted;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
throw new DecryptionFailedException('The data cannot be decrypted');
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Encrypt data with a password chosen by a person, using AES-256-GCM (authenticated encryption) with a key derived
|
|
154
|
+
* from the password and a random 16-byte salt by scrypt (N = 16384, r = 8, p = 1: about 16 MB of memory and a few
|
|
155
|
+
* tens of milliseconds per call, off the main thread). The slow derivation makes guessing the password costly; a
|
|
156
|
+
* strong password still matters. For a random key, {@link encryptByKey} is faster. To check a login password, use
|
|
157
|
+
* {@link PasswordHash} instead.
|
|
158
|
+
* @param data The data to encrypt: a string (encrypted as its UTF-8 bytes) or bytes.
|
|
159
|
+
* @param password The password: a string (used as its UTF-8 bytes) or bytes. Its length is not checked.
|
|
160
|
+
* @returns The encrypted data, base64url encoded without padding, in the format of {@link encryptByKey} with another
|
|
161
|
+
* version byte: the two are not interchangeable.
|
|
162
|
+
* @example
|
|
163
|
+
* ```typescript
|
|
164
|
+
* import {decryptByPassword, encryptByPassword} from 'lakutata/security'
|
|
165
|
+
*
|
|
166
|
+
* const encrypted: string = await encryptByPassword('backup contents', 'a long passphrase of the user')
|
|
167
|
+
* console.log((await decryptByPassword(encrypted, 'a long passphrase of the user')).toString('utf8'))
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
export async function encryptByPassword(data, password) {
|
|
171
|
+
const salt = randomBytes(SALT_LENGTH);
|
|
172
|
+
return seal(PASSWORD_VERSION, salt, await derivePasswordKey(password, salt), data);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Decrypt data encrypted by {@link encryptByPassword}, deriving the key from the password and the salt stored in the
|
|
176
|
+
* data (the same scrypt cost).
|
|
177
|
+
* @param encrypted The encrypted data, base64url as {@link encryptByPassword} returns it.
|
|
178
|
+
* @param password The password it was encrypted with: a string (used as its UTF-8 bytes) or bytes.
|
|
179
|
+
* @returns The decrypted bytes (call `.toString('utf8')` for a string).
|
|
180
|
+
* @throws {DecryptionFailedException} When the password is wrong, or the data was changed, truncated or not produced
|
|
181
|
+
* by {@link encryptByPassword} (data encrypted by {@link encryptByKey} included).
|
|
182
|
+
* @example
|
|
183
|
+
* ```typescript
|
|
184
|
+
* import {decryptByPassword, DecryptionFailedException} from 'lakutata/security'
|
|
185
|
+
*
|
|
186
|
+
* declare const encrypted: string
|
|
187
|
+
* declare const passphrase: string
|
|
188
|
+
*
|
|
189
|
+
* try {
|
|
190
|
+
* console.log((await decryptByPassword(encrypted, passphrase)).toString('utf8'))
|
|
191
|
+
* } catch (error) {
|
|
192
|
+
* if (error instanceof DecryptionFailedException) console.log('Wrong passphrase, or changed data')
|
|
193
|
+
* }
|
|
194
|
+
* ```
|
|
195
|
+
*/
|
|
196
|
+
export async function decryptByPassword(encrypted, password) {
|
|
197
|
+
const part = parts(encrypted, PASSWORD_VERSION);
|
|
198
|
+
const decrypted = part ? open(part, await derivePasswordKey(password, part.salt)) : undefined;
|
|
199
|
+
if (decrypted)
|
|
200
|
+
return decrypted;
|
|
201
|
+
throw new DecryptionFailedException('The data cannot be decrypted');
|
|
202
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
/**
|
|
3
|
+
* Generate a random secret key from the operating system's cryptographically secure generator (`crypto.randomBytes`),
|
|
4
|
+
* suited to the keys of {@link Mac} and {@link Crypt}, {@link hmac} and {@link encryptByKey}, and to random tokens
|
|
5
|
+
* (session IDs, reset links). It is not a password and should be stored as a secret (an environment variable, a vault).
|
|
6
|
+
* @param bytes The number of random bytes; 32 (256 bits) by default, at least 16 for a secret (0 gives an empty
|
|
7
|
+
* string). The keys of {@link Mac} and {@link Crypt} need 12 bytes or more to reach their 16-character minimum.
|
|
8
|
+
* @returns The random bytes, base64url encoded without padding: 43 characters for 32 bytes, 22 for 16.
|
|
9
|
+
* @throws {RangeError} When `bytes` is negative or larger than 2^31 - 1.
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* import {generateSecret} from 'lakutata/security'
|
|
13
|
+
*
|
|
14
|
+
* //A 256-bit key, for MAC_KEY or CRYPT_KEY
|
|
15
|
+
* console.log(generateSecret())
|
|
16
|
+
* //A 128-bit token
|
|
17
|
+
* const token: string = generateSecret(16)
|
|
18
|
+
* console.log(token)
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export function generateSecret(bytes = 32) {
|
|
22
|
+
return randomBytes(bytes).toString('base64url');
|
|
23
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { createHmac } from 'node:crypto';
|
|
2
|
+
import { constantTimeEqual } from './TimingSafeEqual.js';
|
|
3
|
+
import { assertKey } from '../lib/AssertKey.js';
|
|
4
|
+
/**
|
|
5
|
+
* Sign data with a key: compute its hmac, a keyed hash that only a holder of the key can produce. Use it to detect
|
|
6
|
+
* tampering (webhooks, signed links); it does not hide the data, and is not a password hash. The {@link Mac} provider
|
|
7
|
+
* does the same with configured keys and key rotation.
|
|
8
|
+
* @param data The data to sign: a string (signed as its UTF-8 bytes) or bytes.
|
|
9
|
+
* @param key The secret key: a string (used as its UTF-8 bytes, not decoded) or bytes, not empty. Use a random key of
|
|
10
|
+
* 32 bytes, such as {@link generateSecret} returns.
|
|
11
|
+
* @param algorithm The hash function; `'sha256'` by default.
|
|
12
|
+
* @returns The hmac, base64url encoded without padding.
|
|
13
|
+
* @throws {RangeError} When the key is empty.
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import {generateSecret, hmac, verifyHMAC} from 'lakutata/security'
|
|
17
|
+
*
|
|
18
|
+
* const key: string = process.env.WEBHOOK_KEY ?? generateSecret()
|
|
19
|
+
* const body: string = JSON.stringify({order: 42, status: 'paid'})
|
|
20
|
+
* //Sent in a header along with the body
|
|
21
|
+
* const signature: string = hmac(body, key, 'sha256')
|
|
22
|
+
* console.log(verifyHMAC(body, signature, key, 'sha256'))
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export function hmac(data, key, algorithm = 'sha256') {
|
|
26
|
+
assertKey(key);
|
|
27
|
+
return createHmac(algorithm, key).update(data).digest('base64url');
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Check that a signature is the HMAC of data with a key, in a time that does not depend on the signature (see
|
|
31
|
+
* {@link constantTimeEqual}).
|
|
32
|
+
* @param data The signed data, exactly as it was signed (the raw request body, not a re-serialized copy).
|
|
33
|
+
* @param signature The signature to check, base64url encoded without padding as {@link hmac} returns it; a hex or
|
|
34
|
+
* padded signature does not match.
|
|
35
|
+
* @param key The secret key the data was signed with: a string (used as its UTF-8 bytes) or bytes, not empty.
|
|
36
|
+
* @param algorithm The hash function the data was signed with; `'sha256'` by default.
|
|
37
|
+
* @returns `true` when the signature matches.
|
|
38
|
+
* @throws {RangeError} When the key is empty.
|
|
39
|
+
* @example
|
|
40
|
+
* ```typescript
|
|
41
|
+
* import {InvalidSignatureException, verifyHMAC} from 'lakutata/security'
|
|
42
|
+
*
|
|
43
|
+
* declare const rawBody: string
|
|
44
|
+
* declare const signatureHeader: string
|
|
45
|
+
* declare const webhookKey: string
|
|
46
|
+
*
|
|
47
|
+
* if (!verifyHMAC(rawBody, signatureHeader, webhookKey)) {
|
|
48
|
+
* throw new InvalidSignatureException('The signature of the webhook is not valid')
|
|
49
|
+
* }
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export function verifyHMAC(data, signature, key, algorithm = 'sha256') {
|
|
53
|
+
return constantTimeEqual(hmac(data, key, algorithm), signature);
|
|
54
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createHmac, randomBytes, timingSafeEqual } from 'node:crypto';
|
|
2
|
+
/**
|
|
3
|
+
* A random key of the process: the compared values are digested with it, so the comparison does not reveal their length
|
|
4
|
+
*/
|
|
5
|
+
const COMPARISON_KEY = randomBytes(32);
|
|
6
|
+
/**
|
|
7
|
+
* Compare two secrets (signatures, tokens, API keys) in a time that does not depend on their content or their lengths,
|
|
8
|
+
* so an attacker cannot guess a secret by timing the comparisons. Values of different lengths are compared too, and
|
|
9
|
+
* are unequal. Use it instead of `===` whenever one side is a secret; to check a password, use
|
|
10
|
+
* {@link PasswordHash.validate} instead.
|
|
11
|
+
* @param a The first value: a string (compared as its UTF-8 bytes) or bytes.
|
|
12
|
+
* @param b The second value: a string (compared as its UTF-8 bytes) or bytes.
|
|
13
|
+
* @returns `true` when both values hold the same bytes.
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* import {constantTimeEqual} from 'lakutata/security'
|
|
17
|
+
*
|
|
18
|
+
* declare const presentedApiKey: string
|
|
19
|
+
*
|
|
20
|
+
* if (!constantTimeEqual(presentedApiKey, process.env.API_KEY ?? '')) throw new Error('Unauthorized')
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export function constantTimeEqual(a, b) {
|
|
24
|
+
const digestA = createHmac('sha256', COMPARISON_KEY).update(a).digest();
|
|
25
|
+
const digestB = createHmac('sha256', COMPARISON_KEY).update(b).digest();
|
|
26
|
+
return timingSafeEqual(digestA, digestB);
|
|
27
|
+
}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Derived from the upstream index.js (see UPSTREAM.md; BSD-3-Clause, see THIRD_PARTY_NOTICES.md)
|
|
3
|
+
*/
|
|
4
|
+
//bcrypt's own non-standard base64 alphabet
|
|
5
|
+
const BASE64_CODE = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'.split('');
|
|
6
|
+
const BASE64_INDEX = [
|
|
7
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
8
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
9
|
+
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1,
|
|
10
|
+
54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1, -1,
|
|
11
|
+
-1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
|
12
|
+
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, -1, -1, -1, -1, -1,
|
|
13
|
+
-1, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
|
|
14
|
+
43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, -1, -1, -1, -1, -1
|
|
15
|
+
];
|
|
16
|
+
const BCRYPT_SALT_LEN = 16;
|
|
17
|
+
const GENSALT_DEFAULT_LOG2_ROUNDS = 10;
|
|
18
|
+
const BLOWFISH_NUM_ROUNDS = 16;
|
|
19
|
+
//The longest synchronous run of the asynchronous hashing, in milliseconds
|
|
20
|
+
const MAX_EXECUTION_TIME = 100;
|
|
21
|
+
const P_ORIG = [
|
|
22
|
+
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
|
|
23
|
+
0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
|
|
24
|
+
0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b
|
|
25
|
+
];
|
|
26
|
+
const S_ORIG = [
|
|
27
|
+
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96,
|
|
28
|
+
0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
|
|
29
|
+
0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658,
|
|
30
|
+
0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
|
|
31
|
+
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e,
|
|
32
|
+
0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
|
|
33
|
+
0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6,
|
|
34
|
+
0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
|
|
35
|
+
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c,
|
|
36
|
+
0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
|
|
37
|
+
0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1,
|
|
38
|
+
0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
|
|
39
|
+
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a,
|
|
40
|
+
0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
|
|
41
|
+
0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176,
|
|
42
|
+
0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
|
|
43
|
+
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706,
|
|
44
|
+
0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
|
|
45
|
+
0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b,
|
|
46
|
+
0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
|
|
47
|
+
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c,
|
|
48
|
+
0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
|
|
49
|
+
0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a,
|
|
50
|
+
0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
|
|
51
|
+
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760,
|
|
52
|
+
0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
|
|
53
|
+
0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8,
|
|
54
|
+
0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
|
|
55
|
+
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33,
|
|
56
|
+
0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
|
|
57
|
+
0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0,
|
|
58
|
+
0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
|
|
59
|
+
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777,
|
|
60
|
+
0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
|
|
61
|
+
0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705,
|
|
62
|
+
0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
|
|
63
|
+
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e,
|
|
64
|
+
0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
|
|
65
|
+
0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9,
|
|
66
|
+
0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
|
|
67
|
+
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f,
|
|
68
|
+
0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
|
|
69
|
+
0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a, 0x4b7a70e9, 0xb5b32944,
|
|
70
|
+
0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
|
|
71
|
+
0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1, 0x193602a5, 0x75094c29,
|
|
72
|
+
0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
|
|
73
|
+
0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1, 0x4cdd2086, 0x8470eb26,
|
|
74
|
+
0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
|
|
75
|
+
0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737, 0x3e07841c, 0x7fdeae5c,
|
|
76
|
+
0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
|
|
77
|
+
0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd, 0xd19113f9, 0x7ca92ff6,
|
|
78
|
+
0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
|
|
79
|
+
0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41, 0xe238cd99, 0x3bea0e2f,
|
|
80
|
+
0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
|
|
81
|
+
0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af, 0xde9a771f, 0xd9930810,
|
|
82
|
+
0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
|
|
83
|
+
0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c, 0xec7aec3a, 0xdb851dfa,
|
|
84
|
+
0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
|
|
85
|
+
0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd, 0x71dff89e, 0x10314e55,
|
|
86
|
+
0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
|
|
87
|
+
0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e, 0x86e34570, 0xeae96fb1,
|
|
88
|
+
0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
|
|
89
|
+
0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a, 0xc6150eba, 0x94e2ea78,
|
|
90
|
+
0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
|
|
91
|
+
0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66, 0xe3bc4595, 0xa67bc883,
|
|
92
|
+
0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
|
|
93
|
+
0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84, 0x1521b628, 0x29076170,
|
|
94
|
+
0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
|
|
95
|
+
0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14, 0xeecc86bc, 0x60622ca7,
|
|
96
|
+
0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
|
|
97
|
+
0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7, 0x9b540b19, 0x875fa099,
|
|
98
|
+
0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
|
|
99
|
+
0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99, 0x57f584a5, 0x1b227263,
|
|
100
|
+
0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
|
|
101
|
+
0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73, 0x5d4a14d9, 0xe864b7e3,
|
|
102
|
+
0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
|
|
103
|
+
0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105, 0xd81e799e, 0x86854dc7,
|
|
104
|
+
0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
|
|
105
|
+
0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285, 0x095bbf00, 0xad19489d,
|
|
106
|
+
0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
|
|
107
|
+
0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb, 0x7cde3759, 0xcbee7460,
|
|
108
|
+
0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
|
|
109
|
+
0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc, 0x9e447a2e, 0xc3453484,
|
|
110
|
+
0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
|
|
111
|
+
0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20, 0x153e21e7, 0x8fb03d4a,
|
|
112
|
+
0xe6e39f2b, 0xdb83adf7, 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
|
|
113
|
+
0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a,
|
|
114
|
+
0x43b7d4b7, 0x500061af, 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
|
|
115
|
+
0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785,
|
|
116
|
+
0x7fac6dd0, 0x31cb8504, 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
|
|
117
|
+
0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900,
|
|
118
|
+
0x680ec0a4, 0x27a18dee, 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
|
|
119
|
+
0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9,
|
|
120
|
+
0xee39d7ab, 0x3b124e8b, 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
|
|
121
|
+
0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397,
|
|
122
|
+
0x454056ac, 0xba489527, 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
|
|
123
|
+
0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9,
|
|
124
|
+
0x5ef47e1c, 0x9029317c, 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
|
|
125
|
+
0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f,
|
|
126
|
+
0x404779a4, 0x5d886e17, 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
|
|
127
|
+
0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e,
|
|
128
|
+
0xaf664fd1, 0xcad18115, 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
|
|
129
|
+
0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd,
|
|
130
|
+
0x647d0862, 0xe7ccf5f0, 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
|
|
131
|
+
0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8,
|
|
132
|
+
0x991be14c, 0xdb6e6b0d, 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
|
|
133
|
+
0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c,
|
|
134
|
+
0xa091cf0b, 0xd9155ea3, 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
|
|
135
|
+
0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b,
|
|
136
|
+
0x12754ccc, 0x782ef11c, 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
|
|
137
|
+
0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386,
|
|
138
|
+
0xd90cec6e, 0xd5abea2a, 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
|
|
139
|
+
0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0,
|
|
140
|
+
0x7745ae04, 0xd736fccc, 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
|
|
141
|
+
0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2,
|
|
142
|
+
0xf474ef38, 0x8789bdc2, 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
|
|
143
|
+
0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770,
|
|
144
|
+
0x8cd55591, 0xc902de4c, 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
|
|
145
|
+
0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c,
|
|
146
|
+
0x4a99a025, 0x1d6efe10, 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
|
|
147
|
+
0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa,
|
|
148
|
+
0xa002b5c4, 0x0de6d027, 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
|
|
149
|
+
0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63,
|
|
150
|
+
0x53c2dd94, 0xc2c21634, 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
|
|
151
|
+
0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9,
|
|
152
|
+
0x1ac15bb4, 0xd39eb8fc, 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
|
|
153
|
+
0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4,
|
|
154
|
+
0x362abfce, 0xddc6c837, 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
|
|
155
|
+
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742,
|
|
156
|
+
0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
|
|
157
|
+
0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79,
|
|
158
|
+
0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
|
|
159
|
+
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a,
|
|
160
|
+
0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
|
|
161
|
+
0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1,
|
|
162
|
+
0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
|
|
163
|
+
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797,
|
|
164
|
+
0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
|
|
165
|
+
0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6,
|
|
166
|
+
0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
|
|
167
|
+
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba,
|
|
168
|
+
0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
|
|
169
|
+
0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5,
|
|
170
|
+
0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
|
|
171
|
+
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce,
|
|
172
|
+
0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
|
|
173
|
+
0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd,
|
|
174
|
+
0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
|
|
175
|
+
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb,
|
|
176
|
+
0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
|
|
177
|
+
0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc,
|
|
178
|
+
0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
|
|
179
|
+
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc,
|
|
180
|
+
0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
|
|
181
|
+
0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a,
|
|
182
|
+
0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
|
|
183
|
+
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a,
|
|
184
|
+
0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
|
|
185
|
+
0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b,
|
|
186
|
+
0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
|
|
187
|
+
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e,
|
|
188
|
+
0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
|
|
189
|
+
0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623,
|
|
190
|
+
0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
|
|
191
|
+
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a,
|
|
192
|
+
0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
|
|
193
|
+
0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3,
|
|
194
|
+
0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
|
|
195
|
+
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c,
|
|
196
|
+
0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
|
|
197
|
+
0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
|
|
198
|
+
];
|
|
199
|
+
const C_ORIG = [
|
|
200
|
+
0x4f727068, 0x65616e42, 0x65686f6c, 0x64657253, 0x63727944, 0x6f756274
|
|
201
|
+
];
|
|
202
|
+
export { BASE64_CODE, BASE64_INDEX, BCRYPT_SALT_LEN, GENSALT_DEFAULT_LOG2_ROUNDS, BLOWFISH_NUM_ROUNDS, MAX_EXECUTION_TIME, P_ORIG, S_ORIG, C_ORIG };
|