1
1
/**
2
2
* @todo document this module
3
3
*/
4
- import { crypto } from "https://deno.land/ std@0.152.0 /crypto/mod.ts" ;
5
- import { decode , encode } from "https://deno.land/ std@0.152.0 /encoding/base64.ts" ;
6
- import { HmacSha256 } from "https://deno.land/[email protected] /hash/sha256 .ts" ;
4
+ import { crypto } from "std/crypto/mod.ts" ;
5
+ import { decodeBase64 , encodeBase64 } from "std/encoding/base64.ts" ;
6
+ import { hmacSHA256 } from "./hmac .ts" ;
7
7
// dprint-ignore-next-line
8
+ // deno-fmt-ignore
8
9
export type logN = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 ;
9
10
export interface ScryptParameters {
10
11
logN ?: logN ;
@@ -26,27 +27,31 @@ export function formatScrypt(
26
27
const encoder = new TextEncoder ( ) ;
27
28
const result = new Uint8Array ( 96 ) ;
28
29
const dataview = new DataView ( result . buffer ) ;
29
- const hmac = new HmacSha256 ( new Uint8Array ( decode ( rawHash ) ) . subarray ( 32 ) ) ;
30
30
// first 6 bytes are the word "scrypt", 7th byte is 0
31
31
result . set ( [ 115 , 99 , 114 , 121 , 112 , 116 , 0 ] , 0 ) ;
32
32
dataview . setUint8 ( 7 , logN ) ;
33
33
dataview . setUint32 ( 8 , r , false ) ;
34
34
dataview . setUint32 ( 12 , p , false ) ;
35
35
result . set ( typeof salt === "string" ? encoder . encode ( salt ) : salt , 16 ) ;
36
- const hashedResult = crypto . subtle . digestSync ( "SHA-256" , result . subarray ( 0 , 48 ) ) ;
36
+ const hashedResult = crypto . subtle . digestSync (
37
+ "SHA-256" ,
38
+ result . subarray ( 0 , 48 ) ,
39
+ ) ;
37
40
result . set ( new Uint8Array ( hashedResult ) , 48 ) ;
38
- hmac . update ( result . subarray ( 0 , 64 ) ) ;
39
41
result . set (
40
- hmac . array ( ) ,
42
+ hmacSHA256 (
43
+ new Uint8Array ( decodeBase64 ( rawHash ) ) . subarray ( 32 ) ,
44
+ result . subarray ( 0 , 64 ) ,
45
+ ) ,
41
46
64 ,
42
47
) ;
43
48
// encode the result as a base64 string
44
- return encode ( result ) ;
49
+ return encodeBase64 ( result ) ;
45
50
}
46
51
function decomposeScrypt (
47
52
formattedHash : string ,
48
53
) : ScryptParameters {
49
- const bytes : Uint8Array = new Uint8Array ( decode ( formattedHash ) ) ;
54
+ const bytes : Uint8Array = new Uint8Array ( decodeBase64 ( formattedHash ) ) ;
50
55
const dataview : DataView = new DataView ( bytes . buffer ) ;
51
56
const parameters : ScryptParameters = { } ;
52
57
parameters . logN = bytes [ 7 ] as logN ;
@@ -74,15 +79,16 @@ export function formatPHC(
74
79
salt : string | Uint8Array ,
75
80
) : string {
76
81
// convert salt to base64 without padding
77
- salt = encode ( salt ) . replace ( / = / g, "" ) ;
82
+ salt = encodeBase64 ( salt ) . replace ( / = / g, "" ) ;
78
83
rawHash = rawHash . replace ( / = / g, "" ) ;
79
84
return `\$scrypt\$ln=${ logN } ,r=${ r } ,p=${ p } \$${ salt } \$${ rawHash } ` ;
80
85
}
81
86
function decomposePHC ( formattedHash : string ) : ScryptParameters {
82
- const regex = / \$ s c r y p t \$ l n = (?< logN > \d + ) , r = (?< r > \d + ) , p = (?< p > \d + ) \$ (?< salt > [ a - z A - Z 0 - 9 \- \_ \+ \/ \= ] * ) \$ / ;
87
+ const regex =
88
+ / \$ s c r y p t \$ l n = (?< logN > \d + ) , r = (?< r > \d + ) , p = (?< p > \d + ) \$ (?< salt > [ a - z A - Z 0 - 9 \- \_ \+ \/ \= ] * ) \$ / ;
83
89
const parameters : ScryptParameters = formattedHash . match ( regex )
84
90
?. groups as ScryptParameters ;
85
- parameters . salt = new Uint8Array ( decode ( parameters . salt as string ) ) ;
91
+ parameters . salt = new Uint8Array ( decodeBase64 ( parameters . salt as string ) ) ;
86
92
// the PHC format from passlib always uses 32 bytes hashes
87
93
parameters . dklen = 32 ;
88
94
return parameters ;
0 commit comments