@@ -36,16 +36,20 @@ var crypto = require('crypto'),
36
36
* @param {[type] } salt
37
37
* @param {Function } callback err, buffer
38
38
*/
39
- pbkdf2 = function pbkdf2 ( password , salt , callback ) {
39
+ pbkdf2 = function pbkdf2 ( password , salt , iterations , keylength , callback ) {
40
40
crypto . pbkdf2 ( password , salt ,
41
- this . iterations , this . keylength , function ( err , buff ) {
41
+ iterations , keylength , function ( err , hash ) {
42
42
if ( err ) {
43
43
return callback ( err ) ;
44
44
}
45
- callback ( null , buff . toString ( 'base64' ) ) ;
45
+ callback ( null , new Buffer ( hash ) . toString ( 'base64' ) ) ;
46
46
} ) ;
47
47
} ,
48
48
49
+ hashMethods = {
50
+ pbkdf2 : pbkdf2
51
+ } ,
52
+
49
53
/**
50
54
* createSalt(callback)
51
55
*
@@ -56,8 +60,8 @@ var crypto = require('crypto'),
56
60
* @param {Function } callback [description]
57
61
* @return {[type] } [description]
58
62
*/
59
- createSalt = function createSalt ( callback ) {
60
- crypto . randomBytes ( this . keylength , function ( err , buff ) {
63
+ createSalt = function createSalt ( keylength , callback ) {
64
+ crypto . randomBytes ( keylength , function ( err , buff ) {
61
65
if ( err ) {
62
66
return callback ( err ) ;
63
67
}
@@ -77,22 +81,33 @@ var crypto = require('crypto'),
77
81
*/
78
82
toHash = function toHash ( password ,
79
83
callback ) {
84
+ var hashMethod = this . hashMethod ,
85
+ keylength = this . keylength ,
86
+ iterations = this . iterations ;
80
87
81
88
// Create the salt
82
- createSalt . call ( this , function ( err , salt ) {
89
+ createSalt ( keylength , function ( err , salt ) {
83
90
if ( err ) {
84
91
return callback ( err ) ;
85
92
}
86
93
87
- salt = salt . toString ( 'base64' ) ;
88
-
89
94
// Then create the hash
90
- pbkdf2 . call ( this , password , salt , function ( err , hash ) {
95
+ hashMethods [ hashMethod ] ( password , salt ,
96
+ iterations , keylength ,
97
+ function ( err , hash ) {
98
+
91
99
if ( err ) {
92
100
return callback ( err ) ;
93
101
}
94
102
95
- callback ( null , salt + '$' + hash . toString ( 'base64' ) ) ;
103
+ callback ( null , JSON . stringify ( {
104
+ salt : salt ,
105
+ hash : hash ,
106
+ hashMethod : hashMethod ,
107
+ iterations : iterations ,
108
+ keylength : keylength
109
+ } ) ) ;
110
+
96
111
} ) ;
97
112
} . bind ( this ) ) ;
98
113
} ,
@@ -117,6 +132,14 @@ var crypto = require('crypto'),
117
132
return result ;
118
133
} ,
119
134
135
+ parseHash = function parseHash ( encodedHash ) {
136
+ try {
137
+ return JSON . parse ( encodedHash ) ;
138
+ } catch ( err ) {
139
+ return err ;
140
+ }
141
+ } ,
142
+
120
143
/**
121
144
* verify(hash, input, callback)
122
145
*
@@ -129,15 +152,21 @@ var crypto = require('crypto'),
129
152
* @param {Function } callback callback(err, isValid)
130
153
*/
131
154
verify = function verify ( hash , input , callback ) {
132
- var oldHash = hash ,
133
- salt = hash . slice ( 0 , 88 ) ;
155
+ var storedHash = parseHash ( hash ) ;
156
+
157
+ if ( ! hashMethods [ storedHash . hashMethod ] ) {
158
+ return callback ( new Error ( 'Couldn\'t parse stored ' +
159
+ 'hash.' ) ) ;
160
+ }
161
+
162
+ hashMethods [ storedHash . hashMethod ] ( input , storedHash . salt , storedHash . iterations ,
163
+ storedHash . keylength , function ( err , newHash ) {
134
164
135
- pbkdf2 . call ( this , input , salt , function ( err , newHash ) {
136
165
var result ;
137
166
if ( err ) {
138
167
return callback ( err ) ;
139
168
}
140
- callback ( null , constantEquals ( salt + '$' + newHash , oldHash ) ) ;
169
+ callback ( null , constantEquals ( newHash , storedHash . hash ) ) ;
141
170
} ) ;
142
171
} ,
143
172
@@ -154,15 +183,18 @@ var crypto = require('crypto'),
154
183
* @return {Object } credential object
155
184
*/
156
185
configure = function configure ( options ) {
157
- var overrides = pick ( options , [ 'keylength' , 'iterations' ] ) ;
158
- mixIn ( this , overrides ) ;
186
+ mixIn ( this , this . defaults , options ) ;
159
187
return this ;
188
+ } ,
189
+
190
+ defaults = {
191
+ keylength : 66 ,
192
+ iterations : 80000 ,
193
+ hashMethod : 'pbkdf2'
160
194
} ;
161
195
162
- module . exports = {
196
+ module . exports = mixIn ( { } , defaults , {
163
197
hash : toHash ,
164
198
verify : verify ,
165
- configure : configure ,
166
- keylength : 66 ,
167
- iterations : 80000
168
- } ;
199
+ configure : configure
200
+ } ) ;
0 commit comments