@@ -152,6 +152,10 @@ function readFileWithPromise(path: string): Promise<Buffer> {
152
152
} ) ;
153
153
}
154
154
155
+ function sha256Hash ( data : Buffer ) : string {
156
+ return crypto . createHash ( 'sha256' ) . update ( data ) . digest ( 'hex' ) ;
157
+ }
158
+
155
159
/********************
156
160
* AES-256 Encryption
157
161
********************/
@@ -224,6 +228,8 @@ export async function encryptFile(
224
228
return `${ ERROR_MESSAGE_PREFIX } : ${ filePath } failed to be opened for reading.` ;
225
229
}
226
230
231
+ const unencryptedFileDataSHA256 = sha256Hash ( fileDataToEncrypt ) ;
232
+
227
233
// Encrypt the file data, and then disable the cipher
228
234
const cipherText = cipher . update ( fileDataToEncrypt ) ;
229
235
cipher . final ( ) ;
@@ -259,15 +265,25 @@ export async function encryptFile(
259
265
return `${ ERROR_MESSAGE_PREFIX } : ${ encryptedFilePath } failed to be written.` ;
260
266
}
261
267
268
+ // If it was written, let's validate that decrypting it will give us the same SHA256 hash as the encrypted data
269
+ const decryptedFileBufferOrError = await getDecryptedFileContents (
270
+ encryptedFilePath ,
271
+ password ,
272
+ true , // isVerification
262
273
) . catch ( ( error ) => {
263
274
return handleEncryptionOrDecryptionError ( error , encryptedFilePath ) ; // This returns a string error message
264
275
} ) ;
265
276
266
- if ( fs . existsSync ( encryptedFilePath ) ) {
267
- console . log ( 'Successfully encrypted file: ' , encryptedFilePath ) ;
268
- return encryptedFilePath ;
269
- } else {
270
- return `${ ERROR_MESSAGE_PREFIX } : ${ encryptedFilePath } failed to be written.` ;
277
+ // If it's not a Buffer (i.e. it's an error message), return it
278
+ if ( typeof decryptedFileBufferOrError === 'string' ) {
279
+ return decryptedFileBufferOrError ;
280
+ }
281
+
282
+ // Validate the SHA256 hash of the decrypted file
283
+ const decryptedFileSHA256 = sha256Hash ( decryptedFileBufferOrError ) ;
284
+ if ( unencryptedFileDataSHA256 !== decryptedFileSHA256 ) {
285
+ fs . unlinkSync ( encryptedFilePath ) ;
286
+ return `${ ERROR_MESSAGE_PREFIX } : ${ encryptedFilePath } failed to be verified after encryption. It's likely corrupted. The hash of the data before encryption was ${ unencryptedFileDataSHA256 } , and the hash of the data after decryption was ${ decryptedFileSHA256 } .` ;
271
287
}
272
288
273
289
console . log ( 'Successfully encrypted file: ' , encryptedFilePath ) ;
0 commit comments