const crypto = require('crypto');
const fs = require('fs');
// Function to create HMAC for a file
function createHmacForFile(filePath, algorithm, key) {
return new Promise((resolve, reject) => {
const hmac = crypto.createHmac(algorithm, key);
const stream = fs.createReadStream(filePath);
stream.on('data', (data) => {
hmac.update(data);
});
stream.on('end', () => {
const digest = hmac.digest('hex');
resolve(digest);
});
stream.on('error', (error) => {
reject(error);
});
});
}
// Function to verify file integrity
async function verifyFileIntegrity(filePath, storedHmacPath, algorithm, key) {
try {
// Read the stored HMAC
const storedHmac = fs.readFileSync(storedHmacPath, 'utf8').trim();
// Calculate the current HMAC
const currentHmac = await createHmacForFile(filePath, algorithm, key);
// Compare the HMACs
const isValid = currentHmac === storedHmac;
return {
isValid,
storedHmac,
currentHmac
};
} catch (error) {
throw new Error(`Verification failed: ${error.message}`);
}
}
// Secret key (must be the same as used to create the original HMAC)
const secretKey = 'file-authentication-key';
// Example usage
const filePath = 'example.txt';
const hmacPath = `${filePath}.hmac`;
// Verify the file integrity
verifyFileIntegrity(filePath, hmacPath, 'sha256', secretKey)
.then(result => {
console.log(`File: ${filePath}`);
console.log(`HMAC file: ${hmacPath}`);
console.log(`Integrity verified: ${result.isValid}`);
if (!result.isValid) {
console.log('Stored HMAC:', result.storedHmac);
console.log('Current HMAC:', result.currentHmac);
console.log('The file has been modified!');
} else {
console.log('The file is intact and has not been tampered with.');
}
})
.catch(error => {
console.error('Error:', error.message);
});