@@ -166,8 +166,7 @@ function encrypt(data: Buffer, password: string): Buffer {
166166 return Buffer . concat ( [ MAGIC , Buffer . from ( [ FORMAT_V2 ] ) , salt , iv , encrypted , authTag ] ) ;
167167}
168168
169- function decrypt ( data : Buffer , password : string ) : Buffer {
170- const header = parseEncryptedHeader ( data ) ;
169+ function decryptWithHeader ( data : Buffer , password : string , header : BackupHeader ) : Buffer {
171170 const saltStart = header . saltOffset ;
172171 const saltEnd = saltStart + 32 ;
173172 const ivStart = saltEnd ;
@@ -187,9 +186,23 @@ function decrypt(data: Buffer, password: string): Buffer {
187186 const decipher = crypto . createDecipheriv ( 'aes-256-gcm' , key , iv ) ;
188187 decipher . setAuthTag ( authTag ) ;
189188
189+ return Buffer . concat ( [ decipher . update ( encrypted ) , decipher . final ( ) ] ) ;
190+ }
191+
192+ function decrypt ( data : Buffer , password : string ) : Buffer {
193+ const header = parseEncryptedHeader ( data ) ;
190194 try {
191- return Buffer . concat ( [ decipher . update ( encrypted ) , decipher . final ( ) ] ) ;
195+ return decryptWithHeader ( data , password , header ) ;
192196 } catch {
197+ // If we parsed as v2 because data[4] === 0x02, that byte might just be the
198+ // first byte of a v1 salt. Try v1 params before giving up.
199+ if ( header . version === 2 ) {
200+ try {
201+ return decryptWithHeader ( data , password , { version : 1 , iterations : PBKDF2_ITERS_V1 , saltOffset : 4 } ) ;
202+ } catch {
203+ // v1 also failed — genuinely wrong password or corrupted
204+ }
205+ }
193206 throw new Error ( 'Incorrect password or corrupted backup' ) ;
194207 }
195208}
0 commit comments