@1auth/crypto 0.0.0-alpha.58 → 0.0.0-alpha.59
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/index.js +63 -48
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -27,7 +27,7 @@ const defaults = {
|
|
|
27
27
|
asymmetricKeyNamedCurve: 'P-384', // P-512
|
|
28
28
|
asymmetricSignatureHashAlgorithm: undefined, // fallback to defaultHashAlgorithm
|
|
29
29
|
asymmetricSignatureEncoding: undefined, // fallback to defaultEncoding
|
|
30
|
-
|
|
30
|
+
digestChecksumHashAlgorithm: undefined, // fallback to defaultHashAlgorithm
|
|
31
31
|
digestChecksumEncoding: undefined,
|
|
32
32
|
digestChecksumSalt: undefined, // randomChecksumSalt()
|
|
33
33
|
digestChecksumPepper: undefined, // randomChecksumPepper()
|
|
@@ -65,7 +65,7 @@ export default (opt = {}) => {
|
|
|
65
65
|
'@1auth/crypto digestChecksumPepper is empty, use a stored secret made from randomBytes(12). Checksum peppering disabled.'
|
|
66
66
|
)
|
|
67
67
|
}
|
|
68
|
-
options.
|
|
68
|
+
options.digestChecksumHashAlgorithm ??= options.defaultHashAlgorithm
|
|
69
69
|
options.digestChecksumEncoding ??= options.defaultEncoding
|
|
70
70
|
|
|
71
71
|
// Lengths
|
|
@@ -201,69 +201,69 @@ export const createPepperedValue = (
|
|
|
201
201
|
return newValue
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
-
export const createChecksum = (value, {
|
|
205
|
-
|
|
204
|
+
export const createChecksum = (value, { hashAlgorithm, encoding } = {}) => {
|
|
205
|
+
hashAlgorithm ??= options.digestChecksumHashAlgorithm
|
|
206
206
|
encoding ??= options.digestChecksumEncoding
|
|
207
|
-
return createHash(
|
|
207
|
+
return createHash(hashAlgorithm).update(value).digest(encoding)
|
|
208
208
|
}
|
|
209
209
|
export const createSeasonedChecksum = (
|
|
210
210
|
value,
|
|
211
|
-
{
|
|
211
|
+
{ hashAlgorithm, encoding, checksumSalt, checksumPepper } = {}
|
|
212
212
|
) => {
|
|
213
213
|
return createChecksum(
|
|
214
214
|
createPepperedValue(createSaltedValue(value, { checksumSalt }), {
|
|
215
215
|
checksumPepper
|
|
216
216
|
}),
|
|
217
217
|
{
|
|
218
|
-
|
|
218
|
+
hashAlgorithm,
|
|
219
219
|
encoding
|
|
220
220
|
}
|
|
221
221
|
)
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
-
export const createDigest = (value, {
|
|
225
|
-
|
|
226
|
-
const checksum = createChecksum(value, {
|
|
227
|
-
return `${
|
|
224
|
+
export const createDigest = (value, { hashAlgorithm, encoding } = {}) => {
|
|
225
|
+
hashAlgorithm ??= options.digestChecksumHashAlgorithm
|
|
226
|
+
const checksum = createChecksum(value, { hashAlgorithm, encoding })
|
|
227
|
+
return `${hashAlgorithm}:${checksum}`
|
|
228
228
|
}
|
|
229
229
|
export const createSaltedDigest = (
|
|
230
230
|
value,
|
|
231
|
-
{
|
|
231
|
+
{ hashAlgorithm, encoding, checksumSalt } = {}
|
|
232
232
|
) => {
|
|
233
|
-
|
|
233
|
+
hashAlgorithm ??= options.digestChecksumHashAlgorithm
|
|
234
234
|
const checksum = createChecksum(createSaltedValue(value, { checksumSalt }), {
|
|
235
|
-
|
|
235
|
+
hashAlgorithm,
|
|
236
236
|
encoding
|
|
237
237
|
})
|
|
238
|
-
return `${
|
|
238
|
+
return `${hashAlgorithm}:${checksum}`
|
|
239
239
|
}
|
|
240
240
|
export const createPepperedDigest = (
|
|
241
241
|
value,
|
|
242
|
-
{
|
|
242
|
+
{ hashAlgorithm, encoding, checksumPepper, encryptionKey } = {}
|
|
243
243
|
) => {
|
|
244
|
-
|
|
244
|
+
hashAlgorithm ??= options.digestChecksumHashAlgorithm
|
|
245
245
|
const checksum = createChecksum(
|
|
246
246
|
createPepperedValue(value, { checksumPepper, encryptionKey }),
|
|
247
247
|
{
|
|
248
|
-
|
|
248
|
+
hashAlgorithm,
|
|
249
249
|
encoding
|
|
250
250
|
}
|
|
251
251
|
)
|
|
252
|
-
return `${
|
|
252
|
+
return `${hashAlgorithm}:${checksum}`
|
|
253
253
|
}
|
|
254
254
|
export const createSeasonedDigest = (
|
|
255
255
|
value,
|
|
256
|
-
{
|
|
256
|
+
{ hashAlgorithm, encoding, checksumSalt, checksumPepper, encryptionKey } = {}
|
|
257
257
|
) => {
|
|
258
|
-
|
|
258
|
+
hashAlgorithm ??= options.digestChecksumHashAlgorithm
|
|
259
259
|
const checksum = createSeasonedChecksum(value, {
|
|
260
|
-
|
|
260
|
+
hashAlgorithm,
|
|
261
261
|
encoding,
|
|
262
262
|
checksumSalt,
|
|
263
263
|
checksumPepper,
|
|
264
264
|
encryptionKey
|
|
265
265
|
})
|
|
266
|
-
return `${
|
|
266
|
+
return `${hashAlgorithm}:${checksum}`
|
|
267
267
|
}
|
|
268
268
|
|
|
269
269
|
// *** Hashing *** //
|
|
@@ -370,7 +370,7 @@ export const symmetricEncrypt = (
|
|
|
370
370
|
iv.toString(encoding) + authTag.toString(encoding) + encryptedData
|
|
371
371
|
|
|
372
372
|
// add signature to end
|
|
373
|
-
return symmetricSignatureSign(encryptedDataPacket, signatureSecret)
|
|
373
|
+
return symmetricSignatureSign(encryptedDataPacket, { signatureSecret })
|
|
374
374
|
}
|
|
375
375
|
|
|
376
376
|
export const symmetricDecryptFields = (
|
|
@@ -428,10 +428,9 @@ export const symmetricDecrypt = (
|
|
|
428
428
|
encoding ??= 'utf8'
|
|
429
429
|
|
|
430
430
|
// remove signature when successful
|
|
431
|
-
encryptedDataPacket = symmetricSignatureVerify(
|
|
432
|
-
encryptedDataPacket,
|
|
431
|
+
encryptedDataPacket = symmetricSignatureVerify(encryptedDataPacket, {
|
|
433
432
|
signatureSecret
|
|
434
|
-
)
|
|
433
|
+
})
|
|
435
434
|
|
|
436
435
|
if (encryptedDataPacket === false) {
|
|
437
436
|
throw new Error('Signature incorrect')
|
|
@@ -462,7 +461,7 @@ export const symmetricDecrypt = (
|
|
|
462
461
|
authTagLength
|
|
463
462
|
}
|
|
464
463
|
)
|
|
465
|
-
decipher.setAAD(
|
|
464
|
+
decipher.setAAD(sub)
|
|
466
465
|
|
|
467
466
|
decipher.setAuthTag(authTag)
|
|
468
467
|
const data =
|
|
@@ -486,12 +485,11 @@ export const symmetricGenerateSignatureSecret = () => {
|
|
|
486
485
|
|
|
487
486
|
export const symmetricSignatureSign = (
|
|
488
487
|
data,
|
|
489
|
-
signatureSecret
|
|
490
|
-
{ algorithm } = {}
|
|
488
|
+
{ hashAlgorithm, signatureSecret } = {}
|
|
491
489
|
) => {
|
|
492
490
|
signatureSecret ??= options.symmetricSignatureSecret
|
|
493
|
-
|
|
494
|
-
const signature = createHmac(
|
|
491
|
+
hashAlgorithm ??= options.symmetricSignatureHashAlgorithm
|
|
492
|
+
const signature = createHmac(hashAlgorithm, signatureSecret)
|
|
495
493
|
.update(data)
|
|
496
494
|
.digest(options.symmetricSignatureEncoding)
|
|
497
495
|
.replace(/=+$/, '')
|
|
@@ -502,13 +500,18 @@ export const symmetricSignatureSign = (
|
|
|
502
500
|
|
|
503
501
|
export const symmetricSignatureVerify = (
|
|
504
502
|
signedData,
|
|
505
|
-
signatureSecret
|
|
506
|
-
{ algorithm } = {}
|
|
503
|
+
{ hashAlgorithm, signatureSecret } = {}
|
|
507
504
|
) => {
|
|
508
505
|
if (typeof signedData !== 'string') return false
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
506
|
+
let lastIndexOf = signedData.lastIndexOf('.')
|
|
507
|
+
// Test for unsigned
|
|
508
|
+
if (lastIndexOf < 0) {
|
|
509
|
+
lastIndexOf = signedData.length
|
|
510
|
+
}
|
|
511
|
+
const data = signedData.slice(0, lastIndexOf)
|
|
512
|
+
const signedDataExpected = symmetricSignatureSign(data, {
|
|
513
|
+
hashAlgorithm,
|
|
514
|
+
signatureSecret
|
|
512
515
|
})
|
|
513
516
|
return safeEqual(signedData, signedDataExpected) && data
|
|
514
517
|
}
|
|
@@ -519,28 +522,40 @@ export const symmetricRotation = (
|
|
|
519
522
|
oldOptions, // { encryptionKey, signatureSecret, sub, decoding, encoding }, // old
|
|
520
523
|
oldFields = [],
|
|
521
524
|
newOptions, // { encryptionKey, signatureSecret, sub, decoding, encoding }, // new
|
|
522
|
-
newFields
|
|
525
|
+
newFields,
|
|
523
526
|
transform = (data) => {
|
|
524
527
|
return data
|
|
525
528
|
}
|
|
526
529
|
) => {
|
|
530
|
+
newOptions ??= oldOptions
|
|
531
|
+
newFields ??= oldFields
|
|
532
|
+
|
|
527
533
|
if (oldOptions.sub !== newOptions.sub) throw new Error('Mismatching `sub`')
|
|
528
534
|
|
|
535
|
+
oldEncryptedValues = structuredClone(oldEncryptedValues)
|
|
536
|
+
// Don't use structuredClone, converts Buffer to Uint8Array ...
|
|
537
|
+
oldOptions = { ...oldOptions }
|
|
538
|
+
newOptions = { ...newOptions }
|
|
539
|
+
|
|
529
540
|
// decrypt old encryption key
|
|
530
541
|
const { encryptionKey: oldEncryptedKey } = oldEncryptedValues
|
|
531
542
|
delete oldEncryptedValues.encryptionKey
|
|
532
543
|
|
|
533
|
-
|
|
544
|
+
const oldEncryptionKey = symmetricDecryptKey(oldEncryptedKey, oldOptions)
|
|
545
|
+
oldOptions.encryptionKey = oldEncryptionKey
|
|
534
546
|
|
|
535
547
|
// decrypt
|
|
536
548
|
const data = transform(
|
|
537
|
-
symmetricDecryptFields(
|
|
549
|
+
symmetricDecryptFields(
|
|
550
|
+
oldEncryptedValues,
|
|
551
|
+
{ ...oldOptions, encryptionKey: oldEncryptionKey },
|
|
552
|
+
oldFields
|
|
553
|
+
)
|
|
538
554
|
)
|
|
539
555
|
|
|
540
556
|
// rotate encryptionKey
|
|
541
557
|
const { encryptionKey: newEncryptionKey, encryptedKey: newEncryptedKey } =
|
|
542
|
-
symmetricGenerateEncryptionKey(
|
|
543
|
-
|
|
558
|
+
symmetricGenerateEncryptionKey(newOptions.sub, newOptions)
|
|
544
559
|
newOptions.encryptionKey = newEncryptionKey
|
|
545
560
|
|
|
546
561
|
// encrypt
|
|
@@ -578,10 +593,10 @@ export const makeAsymmetricKeys = async () => {
|
|
|
578
593
|
export const makeAsymmetricSignature = async (
|
|
579
594
|
data,
|
|
580
595
|
privateKey,
|
|
581
|
-
{
|
|
596
|
+
{ hashAlgorithm } = {}
|
|
582
597
|
) => {
|
|
583
|
-
|
|
584
|
-
return (await sign(
|
|
598
|
+
hashAlgorithm ??= options.asymmetricSignatureHashAlgorithm
|
|
599
|
+
return (await sign(hashAlgorithm, Buffer.from(data), privateKey)).toString(
|
|
585
600
|
options.asymmetricSignatureEncoding
|
|
586
601
|
)
|
|
587
602
|
}
|
|
@@ -589,11 +604,11 @@ export const verifyAsymmetricSignature = async (
|
|
|
589
604
|
data,
|
|
590
605
|
publicKey,
|
|
591
606
|
signature,
|
|
592
|
-
{
|
|
607
|
+
{ hashAlgorithm } = {}
|
|
593
608
|
) => {
|
|
594
|
-
|
|
609
|
+
hashAlgorithm ??= options.asymmetricSignatureHashAlgorithm
|
|
595
610
|
return await verify(
|
|
596
|
-
|
|
611
|
+
hashAlgorithm,
|
|
597
612
|
Buffer.from(data),
|
|
598
613
|
publicKey,
|
|
599
614
|
Buffer.from(signature, options.asymmetricSignatureEncoding)
|