@1auth/crypto 0.0.0-beta.0 → 0.0.0-beta.2
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/README.md +44 -0
- package/index.js +24 -34
- package/package.json +13 -10
package/README.md
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<h1>@1auth/crypto</h1>
|
|
3
|
+
<!--<img alt="1auth logo" src="https://raw.githubusercontent.com/willfarrell/1auth/main/docs/img/logo.svg"/>-->
|
|
4
|
+
<p><strong>Cryptographic utilities for encryption, hashing, and signing with modern algorithms</strong></p>
|
|
5
|
+
<p>
|
|
6
|
+
<a href="https://github.com/willfarrell/1auth/actions/workflows/test-unit.yml"><img src="https://github.com/willfarrell/1auth/actions/workflows/test-unit.yml/badge.svg" alt="GitHub Actions unit test status"></a>
|
|
7
|
+
<a href="https://github.com/willfarrell/1auth/actions/workflows/test-dast.yml"><img src="https://github.com/willfarrell/1auth/actions/workflows/test-dast.yml/badge.svg" alt="GitHub Actions dast test status"></a>
|
|
8
|
+
<a href="https://github.com/willfarrell/1auth/actions/workflows/test-perf.yml"><img src="https://github.com/willfarrell/1auth/actions/workflows/test-perf.yml/badge.svg" alt="GitHub Actions perf test status"></a>
|
|
9
|
+
<a href="https://github.com/willfarrell/1auth/actions/workflows/test-sast.yml"><img src="https://github.com/willfarrell/1auth/actions/workflows/test-sast.yml/badge.svg" alt="GitHub Actions SAST test status"></a>
|
|
10
|
+
<a href="https://github.com/willfarrell/1auth/actions/workflows/test-lint.yml"><img src="https://github.com/willfarrell/1auth/actions/workflows/test-lint.yml/badge.svg" alt="GitHub Actions lint test status"></a>
|
|
11
|
+
<br/>
|
|
12
|
+
<a href="https://www.npmjs.com/package/@1auth/crypto"><img alt="npm version" src="https://img.shields.io/npm/v/@1auth/crypto.svg"></a>
|
|
13
|
+
<a href="https://packagephobia.com/result?p=@1auth/crypto"><img src="https://packagephobia.com/badge?p=@1auth/crypto" alt="npm install size"></a>
|
|
14
|
+
<a href="https://www.npmjs.com/package/@1auth/crypto">
|
|
15
|
+
<img alt="npm weekly downloads" src="https://img.shields.io/npm/dw/@1auth/crypto.svg"></a>
|
|
16
|
+
<a href="https://www.npmjs.com/package/@1auth/crypto#provenance">
|
|
17
|
+
<img alt="npm provenance" src="https://img.shields.io/badge/provenance-Yes-brightgreen"></a>
|
|
18
|
+
<br/>
|
|
19
|
+
<a href="https://scorecard.dev/viewer/?uri=github.com/willfarrell/1auth"><img src="https://api.scorecard.dev/projects/github.com/willfarrell/1auth/badge" alt="Open Source Security Foundation (OpenSSF) Scorecard"></a>
|
|
20
|
+
<a href="https://slsa.dev"><img src="https://slsa.dev/images/gh-badge-level3.svg" alt="SLSA 3"></a>
|
|
21
|
+
<a href="https://github.com/willfarrell/1auth/blob/main/docs/CODE_OF_CONDUCT.md"><img src="https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg"></a>
|
|
22
|
+
<a href="https://biomejs.dev"><img alt="Checked with Biome" src="https://img.shields.io/badge/Checked_with-Biome-60a5fa?style=flat&logo=biome"></a>
|
|
23
|
+
<a href="https://conventionalcommits.org"><img alt="Conventional Commits" src="https://img.shields.io/badge/Conventional%20Commits-1.0.0-%23FE5196?logo=conventionalcommits&logoColor=white"></a>
|
|
24
|
+
</p>
|
|
25
|
+
<p>You can read the documentation at: <a href="https://1auth.js.org">https://1auth.js.org</a></p>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
## Install
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm install @1auth/crypto
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Documentation and examples
|
|
35
|
+
|
|
36
|
+
For documentation and examples, refer to the main [1auth monorepo on GitHub](https://github.com/willfarrell/1auth) or the [1auth website](https://1auth.js.org).
|
|
37
|
+
|
|
38
|
+
## Contributing
|
|
39
|
+
|
|
40
|
+
Everyone is very welcome to contribute to this repository. Feel free to [raise issues](https://github.com/willfarrell/1auth/issues) or to [submit Pull Requests](https://github.com/willfarrell/1auth/pulls).
|
|
41
|
+
|
|
42
|
+
## License
|
|
43
|
+
|
|
44
|
+
Licensed under [MIT License](LICENSE). Copyright (c) 2020-2026 [will Farrell](https://github.com/willfarrell) and [contributors](https://github.com/willfarrell/1auth/graphs/contributors).
|
package/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
// Copyright 2003 - 2026 will Farrell, and 1Auth contributors.
|
|
2
|
+
// SPDX-License-Identifier: MIT
|
|
1
3
|
import {
|
|
2
4
|
argon2Sync,
|
|
3
5
|
createCipheriv,
|
|
@@ -32,13 +34,17 @@ const defaults = {
|
|
|
32
34
|
digestChecksumEncoding: undefined,
|
|
33
35
|
digestChecksumSalt: undefined, // randomChecksumSalt()
|
|
34
36
|
digestChecksumPepper: undefined, // randomChecksumPepper()
|
|
37
|
+
// Password hashing defaults - based on OWASP Password Storage Cheat Sheet
|
|
38
|
+
// https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html
|
|
39
|
+
// OWASP minimums: 19 MiB memory, 2 iterations, 1 parallelism
|
|
40
|
+
// We use 32 MiB (exceeds minimum) for enhanced security
|
|
35
41
|
secretArgon2Algorithm: "argon2id",
|
|
36
|
-
secretArgon2Version: 19,
|
|
37
|
-
secretArgon2Parallelism: 1, //
|
|
38
|
-
secretArgon2MemoryCost: 15, //
|
|
39
|
-
secretArgon2TimeCost: 3, //
|
|
40
|
-
secretArgon2NonceLength: 16,
|
|
41
|
-
secretArgon2HashLength: 64,
|
|
42
|
+
secretArgon2Version: 19,
|
|
43
|
+
secretArgon2Parallelism: 1, // OWASP: 1 (matches)
|
|
44
|
+
secretArgon2MemoryCost: 15, // 2^15 KiB = 32 MiB (exceeds OWASP minimum of 19 MiB)
|
|
45
|
+
secretArgon2TimeCost: 3, // OWASP: 2 (we use 3 for better security)
|
|
46
|
+
secretArgon2NonceLength: 16,
|
|
47
|
+
secretArgon2HashLength: 64,
|
|
42
48
|
|
|
43
49
|
defaultEncoding: "base64",
|
|
44
50
|
defaultHashAlgorithm: "sha3-384",
|
|
@@ -119,35 +125,12 @@ export const makeOptionsBuffer = (
|
|
|
119
125
|
|
|
120
126
|
export const getOptions = () => options;
|
|
121
127
|
|
|
122
|
-
// *** entropy *** //
|
|
123
|
-
// export const characterPoolSize = (value) => {
|
|
124
|
-
// const chars = value.split('')
|
|
125
|
-
// let min = chars[0].charCodeAt()
|
|
126
|
-
// let max = chars[0].charCodeAt()
|
|
127
|
-
// for(const char of value.split('')) {
|
|
128
|
-
// const code = char.charCodeAt()
|
|
129
|
-
// if (code < min) {
|
|
130
|
-
// min = code
|
|
131
|
-
// } else if (max < code) {
|
|
132
|
-
// max = code
|
|
133
|
-
// }
|
|
134
|
-
// }
|
|
135
|
-
// return max - min
|
|
136
|
-
// }
|
|
137
|
-
|
|
138
128
|
// *** Helpers *** //
|
|
139
129
|
// Ref: https://therootcompany.com/blog/how-many-bits-of-entropy-per-character/
|
|
140
130
|
export const entropyToCharacterLength = (bits, characterPoolSize) => {
|
|
141
131
|
// bits*ln(2)/ln(characterPoolSize)
|
|
142
132
|
return Math.ceil((bits * Math.LN2) / Math.log(characterPoolSize));
|
|
143
133
|
};
|
|
144
|
-
/* export const characterLengthToEntropy = (
|
|
145
|
-
characterLength,
|
|
146
|
-
characterPoolSize,
|
|
147
|
-
) => {
|
|
148
|
-
// log_2(characterPoolSize^characterLength)
|
|
149
|
-
return Math.floor(Math.log2(characterPoolSize ** characterLength));
|
|
150
|
-
}; */
|
|
151
134
|
|
|
152
135
|
// *** Random generators *** //
|
|
153
136
|
export { randomBytes, randomInt, randomUUID } from "node:crypto";
|
|
@@ -177,7 +160,7 @@ export const randomAlphaNumeric = (characterLength) => {
|
|
|
177
160
|
export const randomNumeric = (characterLength) => {
|
|
178
161
|
let value = "";
|
|
179
162
|
for (let i = characterLength; i--; ) {
|
|
180
|
-
value += randomInt(
|
|
163
|
+
value += randomInt(0, 10);
|
|
181
164
|
}
|
|
182
165
|
return value;
|
|
183
166
|
};
|
|
@@ -440,7 +423,7 @@ export const symmetricGenerateEncryptionKey = (
|
|
|
440
423
|
{ encryptionKey, signatureSecret } = {},
|
|
441
424
|
) => {
|
|
442
425
|
encryptionKey ??= options.symmetricEncryptionKey;
|
|
443
|
-
signatureSecret ??= options.
|
|
426
|
+
signatureSecret ??= options.symmetricSignatureSecret;
|
|
444
427
|
|
|
445
428
|
const rowEncryptionKey = symmetricRandomEncryptionKey();
|
|
446
429
|
const rowEncryptedKey = symmetricEncrypt(rowEncryptionKey, {
|
|
@@ -537,7 +520,7 @@ export const symmetricDecryptKey = (
|
|
|
537
520
|
{ sub, encryptionKey, signatureSecret } = {},
|
|
538
521
|
) => {
|
|
539
522
|
encryptionKey ??= options.symmetricEncryptionKey;
|
|
540
|
-
signatureSecret ??= options.
|
|
523
|
+
signatureSecret ??= options.symmetricSignatureSecret;
|
|
541
524
|
return Buffer.from(
|
|
542
525
|
symmetricDecrypt(encryptedKey, {
|
|
543
526
|
encryptionKey,
|
|
@@ -573,7 +556,9 @@ export const symmetricDecrypt = (
|
|
|
573
556
|
);
|
|
574
557
|
|
|
575
558
|
if (encryptedDataPacket === false) {
|
|
576
|
-
throw new Error("Signature incorrect"
|
|
559
|
+
throw new Error("Signature incorrect", {
|
|
560
|
+
cause: { signedEncryptedDataPacket },
|
|
561
|
+
});
|
|
577
562
|
}
|
|
578
563
|
const iv = Buffer.from(
|
|
579
564
|
encryptedDataPacket.substring(0, symmetricEncryptionEncodingLengths.iv),
|
|
@@ -664,7 +649,10 @@ export const symmetricRotation = (
|
|
|
664
649
|
return data;
|
|
665
650
|
},
|
|
666
651
|
) => {
|
|
667
|
-
if (oldOptions.sub !== newOptions.sub)
|
|
652
|
+
if (oldOptions.sub !== newOptions.sub)
|
|
653
|
+
throw new Error("Mismatching `sub`", {
|
|
654
|
+
cause: { sub: oldOptions.sub },
|
|
655
|
+
});
|
|
668
656
|
|
|
669
657
|
const oldEncryptedValuesClone = structuredClone(oldEncryptedValues);
|
|
670
658
|
// Don't use structuredClone, converts Buffer to Uint8Array ...
|
|
@@ -752,6 +740,8 @@ export const verifyAsymmetricSignature = async (
|
|
|
752
740
|
);
|
|
753
741
|
};
|
|
754
742
|
|
|
743
|
+
export const nowInSeconds = () => Math.floor(Date.now() / 1000);
|
|
744
|
+
|
|
755
745
|
export const safeEqual = (input, expected) => {
|
|
756
746
|
const bufferInput = Buffer.from(input);
|
|
757
747
|
const bufferExpected = Buffer.from(expected);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@1auth/crypto",
|
|
3
|
-
"version": "0.0.0-beta.
|
|
4
|
-
"description": "",
|
|
3
|
+
"version": "0.0.0-beta.2",
|
|
4
|
+
"description": "Cryptographic utilities for encryption, hashing, and signing with modern algorithms",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=24"
|
|
@@ -12,18 +12,14 @@
|
|
|
12
12
|
},
|
|
13
13
|
"main": "./index.js",
|
|
14
14
|
"module": "./index.js",
|
|
15
|
+
"sideEffects": false,
|
|
15
16
|
"exports": {
|
|
16
17
|
".": {
|
|
17
|
-
"import":
|
|
18
|
-
"types": "./index.d.ts",
|
|
19
|
-
"default": "./index.js"
|
|
20
|
-
}
|
|
18
|
+
"import": "./index.js"
|
|
21
19
|
}
|
|
22
20
|
},
|
|
23
|
-
"types": "index.d.ts",
|
|
24
21
|
"files": [
|
|
25
|
-
"index.js"
|
|
26
|
-
"index.d.ts"
|
|
22
|
+
"index.js"
|
|
27
23
|
],
|
|
28
24
|
"scripts": {
|
|
29
25
|
"test": "npm run test:unit",
|
|
@@ -34,7 +30,14 @@
|
|
|
34
30
|
"type": "github",
|
|
35
31
|
"url": "https://github.com/sponsors/willfarrell"
|
|
36
32
|
},
|
|
37
|
-
"keywords": [
|
|
33
|
+
"keywords": [
|
|
34
|
+
"1auth",
|
|
35
|
+
"OWASP",
|
|
36
|
+
"ASVS",
|
|
37
|
+
"crypto",
|
|
38
|
+
"encryption",
|
|
39
|
+
"hashing"
|
|
40
|
+
],
|
|
38
41
|
"author": {
|
|
39
42
|
"name": "1auth contributors",
|
|
40
43
|
"url": "https://github.com/willfarrell/1auth/graphs/contributors"
|