nestjs-cryptography 2.2.2 → 3.0.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/README.md +147 -0
- package/dist/cryptography.service.d.ts +21 -23
- package/dist/cryptography.service.js +82 -82
- package/dist/interfaces/cryptography-options.interface.d.ts +1 -1
- package/dist/interfaces/generic-options.interface.d.ts +5 -0
- package/dist/interfaces/generic-options.interface.js +2 -0
- package/dist/interfaces/index.d.ts +1 -0
- package/dist/interfaces/index.js +1 -0
- package/package.json +16 -15
- package/wiki/README.md +41 -0
- package/wiki/babel.config.js +3 -0
- package/wiki/docs/Internals/_category_.json +7 -0
- package/wiki/docs/Internals/create-safe-random-data.mdx +41 -0
- package/wiki/docs/Internals/create-secure-hmac.mdx +31 -0
- package/wiki/docs/Internals/symmetric-data-encrypt.mdx +103 -0
- package/wiki/docs/Internals/symmetric-secure-data-encrypt.mdx +161 -0
- package/wiki/docs/api-reference/_category_.json +7 -0
- package/wiki/docs/api-reference/settings.mdx +199 -0
- package/wiki/docs/guides/_category_.json +7 -0
- package/wiki/docs/guides/generics.mdx +170 -0
- package/wiki/docs/guides/hashing.mdx +258 -0
- package/wiki/docs/guides/hmac.mdx +271 -0
- package/wiki/docs/guides/key-derivation.mdx +101 -0
- package/wiki/docs/guides/password-hashing.mdx +136 -0
- package/wiki/docs/guides/symmetric-encryption.mdx +272 -0
- package/wiki/docs/intro.mdx +148 -0
- package/wiki/docusaurus.config.ts +138 -0
- package/wiki/package.json +48 -0
- package/wiki/sidebars.ts +20 -0
- package/wiki/src/common/timing-attack.mdx +3 -0
- package/wiki/src/common/tips.mdx +18 -0
- package/wiki/src/components/GenerateHexButton/index.tsx +35 -0
- package/wiki/src/components/GenerateHexButton/styles.module.css +10 -0
- package/wiki/src/components/GenericLabel/index.tsx +19 -0
- package/wiki/src/components/HomepageFeatures/index.tsx +70 -0
- package/wiki/src/components/HomepageFeatures/styles.module.css +11 -0
- package/wiki/src/components/RecommendedLabel/index.tsx +19 -0
- package/wiki/src/components/RequiredLabel/index.tsx +12 -0
- package/wiki/src/css/custom.css +30 -0
- package/wiki/src/pages/index.module.css +23 -0
- package/wiki/src/pages/index.tsx +43 -0
- package/wiki/src/pages/markdown-page.md +7 -0
- package/wiki/static/.nojekyll +0 -0
- package/wiki/static/img/gear_api.png +0 -0
- package/wiki/static/img/logo.svg +1 -0
- package/wiki/static/img/nestjs_favicon.ico +0 -0
- package/wiki/static/img/node_crypto.png +0 -0
- package/wiki/static/img/phc_logo.png +0 -0
- package/wiki/static/img/profile.png +0 -0
- package/wiki/versioned_docs/version-2.x/Internals/_category_.json +8 -0
- package/wiki/versioned_docs/version-2.x/Internals/create-secure-hmac.mdx +30 -0
- package/wiki/versioned_docs/version-2.x/Internals/symmetric-secure-data-encrypt.mdx +160 -0
- package/wiki/versioned_docs/version-2.x/api-reference/_category_.json +8 -0
- package/wiki/versioned_docs/version-2.x/api-reference/settings.mdx +197 -0
- package/wiki/versioned_docs/version-2.x/guides/_category_.json +7 -0
- package/wiki/versioned_docs/version-2.x/guides/generics.mdx +133 -0
- package/wiki/versioned_docs/version-2.x/guides/hashing.mdx +229 -0
- package/wiki/versioned_docs/version-2.x/guides/hmac.mdx +198 -0
- package/wiki/versioned_docs/version-2.x/guides/key-derivation.mdx +98 -0
- package/wiki/versioned_docs/version-2.x/guides/password-hashing.mdx +132 -0
- package/wiki/versioned_docs/version-2.x/guides/symmetric-encryption.mdx +107 -0
- package/wiki/versioned_docs/version-2.x/intro.mdx +148 -0
- package/wiki/versioned_sidebars/version-2.x-sidebars.json +8 -0
- package/wiki/versions.json +3 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Hashing
|
|
3
|
+
sidebar_label: Hashing
|
|
4
|
+
sidebar_position: 3
|
|
5
|
+
description: Methods to create generic and secure digests
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
import RequiredLabel from '@site/src/components/RequiredLabel';
|
|
9
|
+
import Tips from '@site/src/common/tips.mdx'
|
|
10
|
+
import TimingAttack from '@site/src/common/timing-attack.mdx'
|
|
11
|
+
|
|
12
|
+
In this section, we will dive into various methods for applying cryptographic [hashes][2] both generically and securely.
|
|
13
|
+
We will cover best practices to ensure that the hashing process is robust against common vulnerabilities.
|
|
14
|
+
Additionally, we will explore secure techniques for comparing hash values,
|
|
15
|
+
focusing on the use of time-safe comparison functions to prevent timing attacks.
|
|
16
|
+
These methods are crucial for ensuring the integrity and security of sensitive data in cryptographic operations.
|
|
17
|
+
|
|
18
|
+
## Create a custom HASH
|
|
19
|
+
|
|
20
|
+
Method to create a hash of a text where you could choose the desires hash algorithm to use `sha1, sha256, sha3-256,...`
|
|
21
|
+
|
|
22
|
+
### `createCustomHash`
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
public createCustomHash (
|
|
26
|
+
algorithm: string,
|
|
27
|
+
data: string,
|
|
28
|
+
outputLength: number = 0,
|
|
29
|
+
): Buffer;
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
#### **Parameters:**
|
|
33
|
+
|
|
34
|
+
| Name | Type | Default | Description |
|
|
35
|
+
|--------------------------------|--------|---------|-------------------------------------------------------------------------------------------------------------|
|
|
36
|
+
| **algorithm** <RequiredLabel/> | string | | Digest algorithm to use (`sha1, sha256, sha3-256,...`) |
|
|
37
|
+
| **data** <RequiredLabel/> | string | | String to hash |
|
|
38
|
+
| **outputLength** | number | 0 | Option to specify the desired output length in bytes when using XOF hash functions. For example: `shake256` |
|
|
39
|
+
|
|
40
|
+
#### **Outputs:**
|
|
41
|
+
|
|
42
|
+
As output, it will return a [Buffer][1] `<Buffer cc 2b.....cd a1 08>`
|
|
43
|
+
|
|
44
|
+
#### **Usage:**
|
|
45
|
+
```typescript
|
|
46
|
+
async hashUserPasswrd(
|
|
47
|
+
plainPassword: string,
|
|
48
|
+
): string {
|
|
49
|
+
const hashedPassword = this.cryptographyService.createCustomHash('sha-256', plainPassword);
|
|
50
|
+
return hashedPassword.toString('hex')
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
[//]: #--------------------#
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
## Verify a custom HASH
|
|
59
|
+
|
|
60
|
+
Method to verify if an existing hash matches the hash of the desired text.
|
|
61
|
+
You need choose the existing hash algorithm type used `sha1, sha256, sha3-256,...`
|
|
62
|
+
|
|
63
|
+
### `verifyCustomHash`
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
public verifyCustomHash (
|
|
67
|
+
algorithm: string,
|
|
68
|
+
data: string,
|
|
69
|
+
oldHash: string | Buffer,
|
|
70
|
+
outputLength: number = 0,
|
|
71
|
+
): boolean;
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
#### **Parameters:**
|
|
75
|
+
|
|
76
|
+
| Name | Type | Default | Description |
|
|
77
|
+
|--------------------------------|------------------|---------|-------------------------------------------------------------------------------------------------------------|
|
|
78
|
+
| **algorithm** <RequiredLabel/> | string | | Digest algorithm to use (`sha1, sha256, sha3-256,...`) |
|
|
79
|
+
| **data** <RequiredLabel/> | string | | String to hash |
|
|
80
|
+
| **oldHash** <RequiredLabel/> | Buffer \| string | | Buffer or string of the existing hash |
|
|
81
|
+
| **outputLength** | number | 0 | Option to specify the desired output length in bytes when using XOF hash functions. For example: `shake256` |
|
|
82
|
+
|
|
83
|
+
#### **Outputs:**
|
|
84
|
+
|
|
85
|
+
As output, it will return `true` if both matches, or `false` if not.
|
|
86
|
+
<TimingAttack/>
|
|
87
|
+
|
|
88
|
+
#### **Usage:**
|
|
89
|
+
```typescript
|
|
90
|
+
async checkUserPassword(
|
|
91
|
+
plainPassword: string,
|
|
92
|
+
hashedPassword: string,
|
|
93
|
+
): boolean {
|
|
94
|
+
const bufferExistingHash = Buffer.from(hashedPassword, 'utf-8');
|
|
95
|
+
return this.cryptographyService.verifyCustomHash('sha-256', plainPassword, bufferExistingHash);
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
[//]: #--------------------#
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
## Create a secure HASH
|
|
104
|
+
|
|
105
|
+
Method to create an extra secure hash of a text.
|
|
106
|
+
|
|
107
|
+
In this case the XOF hash function `shake256` will be used, producing and output of **384 bits** length.
|
|
108
|
+
|
|
109
|
+
### `createSecureHash`
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
public createCustomHash (
|
|
113
|
+
data: string
|
|
114
|
+
): Buffer;
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
#### **Parameters:**
|
|
118
|
+
|
|
119
|
+
| Name | Type | Default | Description |
|
|
120
|
+
|--------------------------------|--------|---------|-------------------------------------------------------------------------------------------------------------|
|
|
121
|
+
| **data** <RequiredLabel/> | string | | String to hash |
|
|
122
|
+
|
|
123
|
+
#### **Outputs:**
|
|
124
|
+
|
|
125
|
+
As output, it will return a [Buffer][1] `<Buffer cc 2b.....cd a1 08>`
|
|
126
|
+
|
|
127
|
+
#### **Usage:**
|
|
128
|
+
```typescript
|
|
129
|
+
async secureHashUserPasswrd(
|
|
130
|
+
plainPassword: string,
|
|
131
|
+
): string {
|
|
132
|
+
const hashedPassword = this.cryptographyService.createSecureHash(plainPassword);
|
|
133
|
+
return hashedPassword.toString('hex')
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
[//]: #--------------------#
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
## Verify a secure HASH
|
|
142
|
+
|
|
143
|
+
Method to verify if an existing hash matches the hash of the desired text.
|
|
144
|
+
:::warning
|
|
145
|
+
Remember that the previous hash must have been generated using [`createSecureHash`](hashing#createsecurehash) method.
|
|
146
|
+
:::
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
### `verifySecureHash`
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
public verifySecureHash (
|
|
153
|
+
data: string,
|
|
154
|
+
oldHash: string | Buffer
|
|
155
|
+
): boolean;
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
#### **Parameters:**
|
|
159
|
+
|
|
160
|
+
| Name | Type | Default | Description |
|
|
161
|
+
|------------------------------|------------------|---------|---------------------------------------|
|
|
162
|
+
| **data** <RequiredLabel/> | string | | String to hash |
|
|
163
|
+
| **oldHash** <RequiredLabel/> | Buffer \| string | | Buffer or string of the existing hash |
|
|
164
|
+
|
|
165
|
+
#### **Outputs:**
|
|
166
|
+
|
|
167
|
+
As output, it will return `true` if both matches, or `false` if not.
|
|
168
|
+
|
|
169
|
+
<TimingAttack/>
|
|
170
|
+
|
|
171
|
+
#### **Usage:**
|
|
172
|
+
```typescript
|
|
173
|
+
async checkUserPassword(
|
|
174
|
+
plainPassword: string,
|
|
175
|
+
hashedPassword: string,
|
|
176
|
+
): boolean {
|
|
177
|
+
const bufferExistingHash = Buffer.from(hashedPassword, 'utf-8');
|
|
178
|
+
return this.cryptographyService.verifySecureHash(plainPassword, bufferExistingHash);
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
[//]: #--------------------#
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
## Create insecure fast HASH
|
|
187
|
+
|
|
188
|
+
Method to create an insecure but fast hash using the _**sha1**_ digest algorithm.
|
|
189
|
+
|
|
190
|
+
:::danger
|
|
191
|
+
This method should not be used if you want to guarantee good security.
|
|
192
|
+
|
|
193
|
+
[Read this article][3]
|
|
194
|
+
:::
|
|
195
|
+
|
|
196
|
+
### `createInsecureFastHash`
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
public createInsecureFastHash (
|
|
200
|
+
data: string
|
|
201
|
+
): Buffer;
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
#### **Parameters:**
|
|
205
|
+
|
|
206
|
+
| Name | Type | Default | Description |
|
|
207
|
+
|------------------------------|------------------|---------|---------------------------------------|
|
|
208
|
+
| **data** <RequiredLabel/> | string | | String to hash |
|
|
209
|
+
|
|
210
|
+
#### **Outputs:**
|
|
211
|
+
|
|
212
|
+
As output, it will return a [Buffer][1] `<Buffer cc 2b.....cd a1 08>`
|
|
213
|
+
|
|
214
|
+
#### **Usage:**
|
|
215
|
+
```typescript
|
|
216
|
+
async exampleFastHashSHA1(): string {
|
|
217
|
+
const sha1Hash = this.cryptographyService.createInsecureFastHash('this is not a secret');
|
|
218
|
+
return sha1Hash.toString('base64')
|
|
219
|
+
}
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
<Tips />
|
|
226
|
+
|
|
227
|
+
[1]: https://nodejs.org/api/buffer.html
|
|
228
|
+
[2]: https://en.wikipedia.org/wiki/Hash_function
|
|
229
|
+
[3]: https://www.schneier.com/blog/archives/2005/02/sha1_broken.html
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: HMAC
|
|
3
|
+
sidebar_label: HMAC
|
|
4
|
+
sidebar_position: 5
|
|
5
|
+
description: Methods to create generic and secure HMACs
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
import RequiredLabel from '@site/src/components/RequiredLabel';
|
|
9
|
+
import Tips from '@site/src/common/tips.mdx'
|
|
10
|
+
import TimingAttack from '@site/src/common/timing-attack.mdx'
|
|
11
|
+
|
|
12
|
+
In this section, we will dive into various methods for applying cryptographic [HMAC hash-based message authentication code][2]
|
|
13
|
+
both generically and securely.
|
|
14
|
+
We will cover best practices to ensure that the hmac process is robust against common vulnerabilities.
|
|
15
|
+
Additionally, we will explore secure techniques for comparing hmac values,
|
|
16
|
+
focusing on the use of time-safe comparison functions to prevent timing attacks.
|
|
17
|
+
These methods are crucial for ensuring the integrity and security of sensitive data in cryptographic operations.
|
|
18
|
+
|
|
19
|
+
## Create a custom HMAC
|
|
20
|
+
|
|
21
|
+
Method to create a hmac of a text where you could choose the desired digest algorithm to use `sha1, sha256, sha3-256,...`
|
|
22
|
+
|
|
23
|
+
### `createCustomHmac`
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
public createCustomHmac (
|
|
27
|
+
algorithm: string,
|
|
28
|
+
key: Buffer,
|
|
29
|
+
data: string,
|
|
30
|
+
): Buffer;
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Parameters:**
|
|
34
|
+
|
|
35
|
+
| Name | Type | Default | Description |
|
|
36
|
+
|--------------------------------|--------|---------|--------------------------------------------------------|
|
|
37
|
+
| **algorithm** <RequiredLabel/> | string | | Digest algorithm to use (`sha1, sha256, sha3-256,...`) |
|
|
38
|
+
| **key** <RequiredLabel/> | Buffer | | Secret key to use on the hmac |
|
|
39
|
+
| **data** <RequiredLabel/> | string | | String to hmac |
|
|
40
|
+
|
|
41
|
+
**Outputs:**
|
|
42
|
+
|
|
43
|
+
As output, it will return a [Buffer][1] `<Buffer cc 2b.....cd a1 08>`
|
|
44
|
+
|
|
45
|
+
#### **Usage:**
|
|
46
|
+
```typescript
|
|
47
|
+
async exampleHmac(
|
|
48
|
+
data: string,
|
|
49
|
+
): string {
|
|
50
|
+
const key = this.cryptographyService.generateSymmetricKey(128);
|
|
51
|
+
const hmacResult = this.cryptographyService.createCustomHmac('sha-512', key, data);
|
|
52
|
+
return hmacResult.toString('hex')
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
[//]: #--------------------#
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
## Verify a custom HMAC
|
|
61
|
+
|
|
62
|
+
Method to verify if an existing hmac matches the hmac of the desired text.
|
|
63
|
+
You need choose the existing hmac algorithm type used `sha1, sha256, sha3-256,...`
|
|
64
|
+
|
|
65
|
+
### `verifyCustomHmac`
|
|
66
|
+
|
|
67
|
+
```typescript
|
|
68
|
+
public verifyCustomHmac (
|
|
69
|
+
algorithm: string,
|
|
70
|
+
key: Buffer,
|
|
71
|
+
data: string,
|
|
72
|
+
oldHmac: string | Buffer,
|
|
73
|
+
): boolean;
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Parameters:**
|
|
77
|
+
|
|
78
|
+
| Name | Type | Default | Description |
|
|
79
|
+
|--------------------------------|------------------|---------|--------------------------------------------------------|
|
|
80
|
+
| **algorithm** <RequiredLabel/> | string | | Digest algorithm to use (`sha1, sha256, sha3-256,...`) |
|
|
81
|
+
| **key** <RequiredLabel/> | Buffer | | Secret key to use on the hmac |
|
|
82
|
+
| **data** <RequiredLabel/> | string | | String to hmac |
|
|
83
|
+
| **oldHmac** <RequiredLabel/> | string \| Buffer | | Buffer or string of the existing hmac |
|
|
84
|
+
|
|
85
|
+
**Outputs:**
|
|
86
|
+
|
|
87
|
+
As output, it will return `true` if both matches, or `false` if not.
|
|
88
|
+
|
|
89
|
+
<TimingAttack/>
|
|
90
|
+
|
|
91
|
+
#### **Usage:**
|
|
92
|
+
```typescript
|
|
93
|
+
async checkHmac(
|
|
94
|
+
oldKey: string,
|
|
95
|
+
existingHmac: string,
|
|
96
|
+
data: string,
|
|
97
|
+
): boolean {
|
|
98
|
+
const bufferExistingHmac = Buffer.from(existingHmac, 'hex');
|
|
99
|
+
const bufferOldKey = Buffer.from(oldKey, 'hex');
|
|
100
|
+
return this.cryptographyService.verifyCustomHmac('sha-512', bufferOldKey, data, bufferExistingHmac);
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
[//]: #--------------------#
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
## Create a secure HMAC
|
|
109
|
+
|
|
110
|
+
Method to create an extra secure hmac of a text.
|
|
111
|
+
|
|
112
|
+
In this case the `sha3-256` digest algorithm will be used.
|
|
113
|
+
|
|
114
|
+
### `createSecureHmac`
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
public createSecureHmac (
|
|
118
|
+
data: string
|
|
119
|
+
): Buffer;
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Parameters:**
|
|
123
|
+
|
|
124
|
+
| Name | Type | Default | Description |
|
|
125
|
+
|--------------------------------|--------|---------|-------------------------------------------------------------------------------------------------------------|
|
|
126
|
+
| **data** <RequiredLabel/> | string | | String to hmac |
|
|
127
|
+
|
|
128
|
+
**Outputs:**
|
|
129
|
+
|
|
130
|
+
As output, it will return a [Buffer][1] `<Buffer cc 2b.....cd a1 08>`
|
|
131
|
+
|
|
132
|
+
#### **Usage:**
|
|
133
|
+
```typescript
|
|
134
|
+
async exampleSecureHmac(
|
|
135
|
+
data: string,
|
|
136
|
+
): string {
|
|
137
|
+
const hmacResult = this.cryptographyService.createSecureHmac(data);
|
|
138
|
+
return hmacResult.toString('hex')
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
[//]: #--------------------#
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
## Verify a secure HMAC
|
|
147
|
+
|
|
148
|
+
Method to verify if an existing hmac matches the hmac of the desired text.
|
|
149
|
+
:::warning
|
|
150
|
+
Remember that the previous hmac must have been generated using [`createSecureHmac`](hmac#createsecurehmac) method.
|
|
151
|
+
:::
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
### `verifySecureHmac`
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
public verifySecureHmac (
|
|
158
|
+
data: string,
|
|
159
|
+
oldHmac: string | Buffer
|
|
160
|
+
): boolean;
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**Parameters:**
|
|
164
|
+
|
|
165
|
+
| Name | Type | Default | Description |
|
|
166
|
+
|------------------------------|------------------|---------|---------------------------------------|
|
|
167
|
+
| **data** <RequiredLabel/> | string | | String to hmac |
|
|
168
|
+
| **oldHmac** <RequiredLabel/> | Buffer \| string | | Buffer or string of the existing hmac |
|
|
169
|
+
|
|
170
|
+
**Outputs:**
|
|
171
|
+
|
|
172
|
+
As output, it will return `true` if both matches, or `false` if not.
|
|
173
|
+
|
|
174
|
+
<TimingAttack/>
|
|
175
|
+
|
|
176
|
+
#### **Usage:**
|
|
177
|
+
```typescript
|
|
178
|
+
async exampleVerifySecureHmac(
|
|
179
|
+
data: string,
|
|
180
|
+
existingHmac: string,
|
|
181
|
+
): boolean {
|
|
182
|
+
const bufferExistingHmac = Buffer.from(existingHmac, 'hex');
|
|
183
|
+
return this.cryptographyService.verifySecureHmac(data, bufferExistingHmac);
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
[//]: #--------------------#
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
<Tips />
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
[1]: https://nodejs.org/api/buffer.html
|
|
198
|
+
[2]: https://en.wikipedia.org/wiki/HMAC
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Key Derivation
|
|
3
|
+
sidebar_label: Key Derivation
|
|
4
|
+
sidebar_position: 2
|
|
5
|
+
description: Methods to use KDF (Key Derivation Function)
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
import RequiredLabel from '@site/src/components/RequiredLabel';
|
|
9
|
+
import Tips from '@site/src/common/tips.mdx'
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
The upcoming section will delve into methods for generating cryptographically secure keys from user-provided passwords.
|
|
13
|
+
This process is crucial because raw passwords are often not secure enough for cryptographic purposes
|
|
14
|
+
due to their relatively low entropy. By using a key derivation function, we can transform these passwords
|
|
15
|
+
into secure keys that are suitable for encryption, hashing, or other cryptographic operations.
|
|
16
|
+
|
|
17
|
+
We will be using **Argon2** for this purpose, which is one of the most secure and modern key derivation functions available.
|
|
18
|
+
Argon2 is specifically designed to resist attacks such as brute force and side-channel attacks
|
|
19
|
+
by incorporating memory-hard and CPU-intensive computations. This makes it an ideal choice for
|
|
20
|
+
converting user passwords into robust cryptographic keys.
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
## Derive a key
|
|
25
|
+
|
|
26
|
+
Method to derive a user supplied key into a cryptographically secure one.
|
|
27
|
+
|
|
28
|
+
### `deriveMasterKey`
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
public deriveMasterKey (
|
|
33
|
+
masterKey: string | Buffer,
|
|
34
|
+
salt: Buffer,
|
|
35
|
+
length: number,
|
|
36
|
+
): Promise<Buffer>;
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
#### **Parameters:**
|
|
41
|
+
|
|
42
|
+
| Name | Type | Default | Description |
|
|
43
|
+
|--------------------------------|---------|---------|-----------------------------------------------------|
|
|
44
|
+
| **masterKey** <RequiredLabel/> | boolean | false | MasterKey of password to derive |
|
|
45
|
+
| **salt** <RequiredLabel/> | Buffer | false | Salt to increase the security of the key derivation |
|
|
46
|
+
| **length** <RequiredLabel/> | number | false | The desired derived output key length |
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
#### **Module Parameters:**
|
|
50
|
+
|
|
51
|
+
:::info
|
|
52
|
+
Internally, this method uses certain parameters that are defined at the module level during initialization,
|
|
53
|
+
as we have seen [previously][2]. The internal parameters used and their corresponding configuration keys are as follows:
|
|
54
|
+
|
|
55
|
+
- **hashLength**: Specifies the length of the resulting derived key.
|
|
56
|
+
This is set via [`kdf.defaultOutputKeyLength`][3] and determines the size of the final hash in bytes.
|
|
57
|
+
|
|
58
|
+
- **type**: Defines the variant of Argon2 to use (_argon2i_, _argon2d_, or _argon2id_).
|
|
59
|
+
This is configured using [`kdf.argon2Type`][4].
|
|
60
|
+
|
|
61
|
+
- **memoryCost**: Sets the amount of memory (in KB) that the algorithm will use during the hashing process.
|
|
62
|
+
This value is determined by [`kdf.memoryCost`][5] and plays a critical role in resisting brute-force attacks.
|
|
63
|
+
|
|
64
|
+
- **timeCost**: Specifies the number of iterations or the amount of computational work Argon2 will perform.
|
|
65
|
+
It is defined via [`kdf.timeCost`][6] to ensure a balance between security and performance.
|
|
66
|
+
:::
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
#### **Outputs:**
|
|
70
|
+
|
|
71
|
+
As output, it will return a [Buffer][1] `<Buffer cc 2b.....cd a1 08>`
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
#### **Usage:**
|
|
75
|
+
```typescript
|
|
76
|
+
async deriveSecureKeyFromMasterKey(
|
|
77
|
+
key: string,
|
|
78
|
+
): Promise<string> {
|
|
79
|
+
const keyBuffer = Buffer.from(key, 'utf-8');
|
|
80
|
+
const salt = this.cryptographyService.generateSymmetricKey(128);
|
|
81
|
+
const derivedKey = await this.cryptographyService.deriveMasterKey(keyBuffer, salt.export(), 256)
|
|
82
|
+
return derivedKey.toString('hex')
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
<Tips />
|
|
90
|
+
|
|
91
|
+
[1]: https://nodejs.org/api/buffer.html
|
|
92
|
+
|
|
93
|
+
[2]: ../intro#configuration
|
|
94
|
+
|
|
95
|
+
[3]: ../api-reference/settings#defaultoutputkeylength
|
|
96
|
+
[4]: ../api-reference/settings#argon2type
|
|
97
|
+
[5]: ../api-reference/settings#memorycost
|
|
98
|
+
[6]: ../api-reference/settings#timecost
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Password Hashing
|
|
3
|
+
sidebar_label: Password Hashing
|
|
4
|
+
sidebar_position: 4
|
|
5
|
+
description: Methods to securely hash passwords (Argon2)
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
import RequiredLabel from '@site/src/components/RequiredLabel';
|
|
9
|
+
import Tips from '@site/src/common/tips.mdx'
|
|
10
|
+
import TimingAttack from '@site/src/common/timing-attack.mdx'
|
|
11
|
+
|
|
12
|
+
In this section, we will explore how to securely hash passwords using [Argon2][2],
|
|
13
|
+
one of the most advanced and secure password-hashing algorithms available today.
|
|
14
|
+
Developed as a winner of the [Password Hashing Competition (PHC)][1], Argon2 is designed to protect against brute-force attacks,
|
|
15
|
+
both by consuming significant computational resources and by utilizing memory-hard functions.
|
|
16
|
+
This makes it a preferred choice for modern security practices.
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
## Create Argon2 hash
|
|
21
|
+
|
|
22
|
+
Method to create a hash of a text/password using Argon2 algorithm.
|
|
23
|
+
|
|
24
|
+
### `createArgonHashFromPassword`
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
public createArgonHashFromPassword (
|
|
28
|
+
data: string | Buffer,
|
|
29
|
+
): string;
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
**Parameters:**
|
|
34
|
+
|
|
35
|
+
| Name | Type | Default | Description |
|
|
36
|
+
|---------------------------|------------------|---------|------------------|
|
|
37
|
+
| **data** <RequiredLabel/> | string \| Buffer | | Password to hash |
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
**Module Parameters:**
|
|
41
|
+
|
|
42
|
+
:::info
|
|
43
|
+
Internally, this method uses certain parameters that are defined at the module level during initialization,
|
|
44
|
+
as we have seen [previously][4]. The internal parameters used and their corresponding configuration keys are as follows:
|
|
45
|
+
|
|
46
|
+
- **hashLength**: Specifies the length of the resulting hash.
|
|
47
|
+
This is set via [`hashing.password.outputKeyLength`][5] and determines the size of the final hash in bytes.
|
|
48
|
+
|
|
49
|
+
- **type**: Defines the variant of Argon2 to use (_argon2i_, _argon2d_, or _argon2id_).
|
|
50
|
+
This is configured using [`hashing.password.argon2Type`][6].
|
|
51
|
+
|
|
52
|
+
- **memoryCost**: Sets the amount of memory (in KB) that the algorithm will use during the hashing process.
|
|
53
|
+
This value is determined by [`hashing.password.memoryCost`][7] and plays a critical role in resisting brute-force attacks.
|
|
54
|
+
|
|
55
|
+
- **timeCost**: Specifies the number of iterations or the amount of computational work Argon2 will perform.
|
|
56
|
+
It is defined via [`hashing.password.timeCost`][8] to ensure a balance between security and performance.
|
|
57
|
+
:::
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
**Outputs:**
|
|
61
|
+
|
|
62
|
+
As output, it will return a string of type: `$argon2i$v=19$m=4096,t=3,p=1$c2g56.....jk7A`
|
|
63
|
+
|
|
64
|
+
> Where the options `argon2i`, `v=19`, `m=4096`, `t=3` and `p=1` may vary
|
|
65
|
+
depending on the [options][3] supplied to CryptographyModule when it has been [configured][4].
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
**Usage:**
|
|
69
|
+
```typescript
|
|
70
|
+
async secureUserPassword(
|
|
71
|
+
plainPassword: string,
|
|
72
|
+
): Promise<string> {
|
|
73
|
+
const _buffer = Buffer.from(plainPassword, 'utf-8');
|
|
74
|
+
const hashedPassword = await this.cryptographyService.createArgonHashFromPassword(_buffer);
|
|
75
|
+
return hashedPassword.toString();
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
## Verify Argon2 hash
|
|
82
|
+
|
|
83
|
+
Method to verify if an existing Argon2 hash matches the desired text/password.
|
|
84
|
+
|
|
85
|
+
### `verifyArgonHashFromPassword`
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
public verifyArgonHashFromPassword (
|
|
89
|
+
hash: string,
|
|
90
|
+
data: string | Buffer,
|
|
91
|
+
): Promise<boolean>;
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Parameters:**
|
|
95
|
+
|
|
96
|
+
| Name | Type | Default | Description |
|
|
97
|
+
|---------------------------|------------------|---------|-----------------------------|
|
|
98
|
+
| **hash** <RequiredLabel/> | string | | String of the existing hash |
|
|
99
|
+
| **data** <RequiredLabel/> | Buffer \| string | | Buffer or string to verify |
|
|
100
|
+
|
|
101
|
+
**Outputs:**
|
|
102
|
+
|
|
103
|
+
As output, it will return `true` if both matches, or `false` if not.
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
**Usage:**
|
|
107
|
+
```typescript
|
|
108
|
+
async checkUserPassword(
|
|
109
|
+
plainPassword: string,
|
|
110
|
+
hashedPassword: string
|
|
111
|
+
): Promise<boolean> {
|
|
112
|
+
const _buffer = Buffer.from(plainPassword, 'utf-8');
|
|
113
|
+
return await this.cryptographyService.verifyArgonHashFromPassword(hashedPassword, plainPassword)
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
<Tips />
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
[1]: https://www.password-hashing.net
|
|
124
|
+
[2]: https://github.com/P-H-C/phc-winner-argon2/blob/master/argon2-specs.pdf
|
|
125
|
+
|
|
126
|
+
[3]: ../api-reference/settings
|
|
127
|
+
[4]: ../intro#configuration
|
|
128
|
+
|
|
129
|
+
[5]: ../api-reference/settings#outputkeylength
|
|
130
|
+
[6]: ../api-reference/settings#argon2type-1
|
|
131
|
+
[7]: ../api-reference/settings#memorycost-1
|
|
132
|
+
[8]: ../api-reference/settings#timecost-1
|