116 lines
4.0 KiB
JavaScript
116 lines
4.0 KiB
JavaScript
const crypto = require('crypto');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
async function readKeyFromFile(filePath) {
|
|
try {
|
|
await fs.promises.access(filePath, fs.constants.F_OK);
|
|
return fs.promises.readFile(filePath); // Use asynchronous readFile
|
|
} catch (error) {
|
|
console.error('Error reading key file:', error);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// Paths to the key files remain the same
|
|
const IV_FILE_PATH = path.join(__dirname, '..', '..', 'iv.key');
|
|
const SECRET_KEY_FILE_PATH = path.join(__dirname, '..', '..', 'secret.key');
|
|
|
|
async function encryptFileInPlace(filePath) {
|
|
// Await the resolution of these promises
|
|
const IV = await readKeyFromFile(IV_FILE_PATH);
|
|
const SECRET_KEY = await readKeyFromFile(SECRET_KEY_FILE_PATH);
|
|
|
|
if (!IV || !SECRET_KEY) {
|
|
throw new Error('Failed to load IV or Secret Key');
|
|
}
|
|
|
|
const tempEncryptedFilePath = filePath + '.enc'; // Temporary encrypted file
|
|
return new Promise((resolve, reject) => {
|
|
const cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(SECRET_KEY), IV);
|
|
const input = fs.createReadStream(filePath);
|
|
const output = fs.createWriteStream(tempEncryptedFilePath);
|
|
|
|
input.pipe(cipher).pipe(output);
|
|
|
|
output.on('finish', () => {
|
|
fs.rename(tempEncryptedFilePath, filePath, (err) => {
|
|
if (err) reject(err);
|
|
else resolve('File encrypted successfully and replaced original.');
|
|
});
|
|
});
|
|
output.on('error', reject);
|
|
});
|
|
}
|
|
|
|
async function decryptFileInPlace(filePath) {
|
|
// Await the resolution of these promises
|
|
const IV = await readKeyFromFile(IV_FILE_PATH);
|
|
const SECRET_KEY = await readKeyFromFile(SECRET_KEY_FILE_PATH);
|
|
|
|
if (!IV || !SECRET_KEY) {
|
|
throw new Error('Failed to load IV or Secret Key');
|
|
}
|
|
|
|
const tempDecryptedFilePath = filePath + '.dec'; // Temporary decrypted file
|
|
return new Promise((resolve, reject) => {
|
|
const decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(SECRET_KEY), IV);
|
|
const input = fs.createReadStream(filePath);
|
|
const output = fs.createWriteStream(tempDecryptedFilePath);
|
|
|
|
input.pipe(decipher).pipe(output);
|
|
|
|
output.on('finish', () => {
|
|
fs.rename(tempDecryptedFilePath, filePath, (err) => {
|
|
if (err) reject(err);
|
|
else resolve('File decrypted successfully and replaced original.');
|
|
});
|
|
});
|
|
output.on('error', reject);
|
|
});
|
|
}
|
|
|
|
function cryptForKey(content, key, decrypt = false) {
|
|
const algorithm = 'aes-256-ctr';
|
|
const secretKey = crypto.createHash('sha256').update(String(key)).digest('base64').substr(0, 32);
|
|
let cipher;
|
|
|
|
if (decrypt) {
|
|
cipher = crypto.createDecipheriv(algorithm, secretKey, Buffer.alloc(16, 0)); // Using a zeroed IV for CTR
|
|
} else {
|
|
cipher = crypto.createCipheriv(algorithm, secretKey, Buffer.alloc(16, 0));
|
|
}
|
|
|
|
return Buffer.concat([cipher.update(content), cipher.final()]);
|
|
}
|
|
|
|
// Encrypts a file in place with a given key
|
|
async function encryptFileWithKey(filePath, key) {
|
|
try {
|
|
const fileContent = await fs.promises.readFile(filePath);
|
|
const encryptedContent = cryptForKey(fileContent, key, false);
|
|
await fs.promises.writeFile(filePath, encryptedContent);
|
|
console.log(`File encrypted successfully: ${filePath}`);
|
|
} catch (error) {
|
|
console.error(`Error encrypting file: ${error.message}`);
|
|
}
|
|
}
|
|
|
|
async function decryptFileWithKey(filePath, key) {
|
|
try {
|
|
const fileContent = await fs.promises.readFile(filePath);
|
|
const decryptedContent = cryptForKey(fileContent, key, true);
|
|
await fs.promises.writeFile(filePath, decryptedContent);
|
|
console.log(`File decrypted successfully: ${filePath}`);
|
|
} catch (error) {
|
|
console.error(`Error decrypting file: ${error.message}`);
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
encryptFileInPlace,
|
|
decryptFileInPlace,
|
|
encryptFileWithKey,
|
|
decryptFileWithKey,
|
|
}
|