electron: [Bug]: safeStorage.decryptString - Error while decrypting the ciphertext
Preflight Checklist
- I have read the Contributing Guidelines for this project.
- I agree to follow the Code of Conduct that this project adheres to.
- I have searched the issue tracker for a bug report that matches the one I want to file, without success.
Electron Version
16.0.7
What operating system are you using?
macOS
Operating System Version
macOS Monterey 12.1
What arch are you using?
x64
Last Known Working Electron version
No response
Expected Behavior
safeStorage.decryptString(buffer) should decrypt a previously encrypted string (using safeStorage.encryptString(plainText))
Given the following module for storing settings for an application.
Settings are stored to a file and retrieved on next app start.
Sensitive information, e.g. personalAccessToken should only be stored encrypted.
const { join } = require('path')
const { existsSync, promises: { readFile, writeFile } } = require('fs')
const { app, safeStorage } = require('electron')
const { Buffer } = require('buffer')
const userData = app.getPath('userData')
const settingsPath = join(userData, 'settings.json')
const defaultSettings = {
baseUrl: '',
personalAccessToken: '',
fetchInterval: 5
}
const encrypt = plainText => {
const buffer = safeStorage.encryptString(plainText)
const encrypted = buffer.toString('base64')
return encrypted
}
const decrypt = encrypted => {
const buffer = Buffer.from(encrypted, 'base64')
const plainText = safeStorage.decryptString(buffer)
return plainText
}
module.exports = {
async save ({ baseUrl, personalAccessToken, fetchInterval }) {
const json = JSON.stringify({
baseUrl,
personalAccessToken: encrypt(personalAccessToken),
fetchInterval
})
await writeFile(settingsPath, json, 'utf8')
},
async load () {
if (!existsSync(settingsPath)) {
return defaultSettings
}
const json = await readFile(settingsPath, 'utf8')
const { baseUrl, personalAccessToken, fetchInterval } = JSON.parse(json)
return {
...defaultSettings,
baseUrl,
personalAccessToken: decrypt(personalAccessToken),
fetchInterval
}
}
}
Actual Behavior
safeStorage.encryptString(plainText) works as expected but whenever a safeStorage.decryptString(buffer) is called it throws an error:
Error while decrypting the ciphertext provided to safeStorage.decryptString.
Testcase Gist URL
No response
Additional Information
No response
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 3
- Comments: 23 (5 by maintainers)
Does this potentially have to do with saving the encrypted string to a file, e.g. using
electron-store? In my case I can run this part correctly:But once I round-trip through
electron-store, it no longer is able to decrypt the string.I resolved this issue by saving encrypted string with base64 encoding (toString has utf8 encoding by default, and with it not working for me, too)
https://github.com/electron/electron/blob/main/docs/api/safe-storage.md#safestoragegetselectedstoragebackend-linux
Try to use safeStorage after any browserWindow created. It helped me to figure out with the same error on MacOs.