Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Store SQLCipher decryption key in separate file
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.
- Loading branch information
1 parent
006700f
commit 496ebf2
Showing
3 changed files
with
93 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters