11/**
22 * @todo document this module
33 */
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/std@0.152.0/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" ;
77// dprint-ignore-next-line
8+ // deno-fmt-ignore
89export 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 ;
910export interface ScryptParameters {
1011 logN ?: logN ;
@@ -26,27 +27,31 @@ export function formatScrypt(
2627 const encoder = new TextEncoder ( ) ;
2728 const result = new Uint8Array ( 96 ) ;
2829 const dataview = new DataView ( result . buffer ) ;
29- const hmac = new HmacSha256 ( new Uint8Array ( decode ( rawHash ) ) . subarray ( 32 ) ) ;
3030 // first 6 bytes are the word "scrypt", 7th byte is 0
3131 result . set ( [ 115 , 99 , 114 , 121 , 112 , 116 , 0 ] , 0 ) ;
3232 dataview . setUint8 ( 7 , logN ) ;
3333 dataview . setUint32 ( 8 , r , false ) ;
3434 dataview . setUint32 ( 12 , p , false ) ;
3535 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+ ) ;
3740 result . set ( new Uint8Array ( hashedResult ) , 48 ) ;
38- hmac . update ( result . subarray ( 0 , 64 ) ) ;
3941 result . set (
40- hmac . array ( ) ,
42+ hmacSHA256 (
43+ new Uint8Array ( decodeBase64 ( rawHash ) ) . subarray ( 32 ) ,
44+ result . subarray ( 0 , 64 ) ,
45+ ) ,
4146 64 ,
4247 ) ;
4348 // encode the result as a base64 string
44- return encode ( result ) ;
49+ return encodeBase64 ( result ) ;
4550}
4651function decomposeScrypt (
4752 formattedHash : string ,
4853) : ScryptParameters {
49- const bytes : Uint8Array = new Uint8Array ( decode ( formattedHash ) ) ;
54+ const bytes : Uint8Array = new Uint8Array ( decodeBase64 ( formattedHash ) ) ;
5055 const dataview : DataView = new DataView ( bytes . buffer ) ;
5156 const parameters : ScryptParameters = { } ;
5257 parameters . logN = bytes [ 7 ] as logN ;
@@ -74,15 +79,16 @@ export function formatPHC(
7479 salt : string | Uint8Array ,
7580) : string {
7681 // convert salt to base64 without padding
77- salt = encode ( salt ) . replace ( / = / g, "" ) ;
82+ salt = encodeBase64 ( salt ) . replace ( / = / g, "" ) ;
7883 rawHash = rawHash . replace ( / = / g, "" ) ;
7984 return `\$scrypt\$ln=${ logN } ,r=${ r } ,p=${ p } \$${ salt } \$${ rawHash } ` ;
8085}
8186function 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 \- \_ \+ \/ \= ] * ) \$ / ;
8389 const parameters : ScryptParameters = formattedHash . match ( regex )
8490 ?. groups as ScryptParameters ;
85- parameters . salt = new Uint8Array ( decode ( parameters . salt as string ) ) ;
91+ parameters . salt = new Uint8Array ( decodeBase64 ( parameters . salt as string ) ) ;
8692 // the PHC format from passlib always uses 32 bytes hashes
8793 parameters . dklen = 32 ;
8894 return parameters ;
0 commit comments