
First, we write the key a whole lot less. We write it on creation, then never again. Second, it's in a file we control very closely. Instead of blindly regenerating the key if the target file generates an error on read, we block startup unless the error is 'ENOENT' - the file isn't there at all. This still allows for the key.txt file to be deleted or corrupted somehow, but it should be a lot less common than the high-traffic config.json used for window location and media permissions.
62 lines
1.4 KiB
JavaScript
62 lines
1.4 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
const crypto = require('crypto');
|
|
|
|
const { app } = require('electron');
|
|
|
|
const ENCODING = 'utf8';
|
|
const userDataPath = app.getPath('userData');
|
|
const targetPath = path.join(userDataPath, 'key.txt');
|
|
|
|
module.exports = {
|
|
get,
|
|
set,
|
|
initialize,
|
|
remove,
|
|
};
|
|
|
|
function get() {
|
|
try {
|
|
const key = fs.readFileSync(targetPath, ENCODING);
|
|
console.log('key/get: Successfully read key file');
|
|
return key;
|
|
} catch (error) {
|
|
if (error.code === 'ENOENT') {
|
|
console.log('key/get: Could not find key file, returning null');
|
|
return null;
|
|
}
|
|
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
function set(key) {
|
|
console.log('key/set: Saving key to disk');
|
|
fs.writeFileSync(targetPath, key, ENCODING);
|
|
}
|
|
|
|
function remove() {
|
|
console.log('key/remove: Deleting key from disk');
|
|
fs.unlinkSync(targetPath);
|
|
}
|
|
|
|
function initialize({ userConfig }) {
|
|
const keyFromConfig = userConfig.get('key');
|
|
const keyFromStore = get();
|
|
|
|
let key = keyFromStore || keyFromConfig;
|
|
if (!key) {
|
|
console.log(
|
|
'key/initialize: Generating new encryption key, since we did not find it on disk'
|
|
);
|
|
// https://www.zetetic.net/sqlcipher/sqlcipher-api/#key
|
|
key = crypto.randomBytes(32).toString('hex');
|
|
set(key);
|
|
} else if (keyFromConfig) {
|
|
set(key);
|
|
console.log('key/initialize: Removing key from config.json');
|
|
userConfig.delete('key');
|
|
}
|
|
|
|
return key;
|
|
}
|