From 8da63dae42fee48f1f4443d9ede32afeb6b80a51 Mon Sep 17 00:00:00 2001 From: Tuditi <45079109+Tuditi@users.noreply.github.com> Date: Tue, 5 Mar 2024 11:08:00 +0100 Subject: [PATCH] Feat: store pin hash (#2058) * feat: store pin hash * feat: use salt --------- Co-authored-by: Nicole O'Brien --- .../lib/electron/managers/pincode.manager.ts | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/packages/desktop/lib/electron/managers/pincode.manager.ts b/packages/desktop/lib/electron/managers/pincode.manager.ts index e10d0d1755..fd0aa5a3cb 100644 --- a/packages/desktop/lib/electron/managers/pincode.manager.ts +++ b/packages/desktop/lib/electron/managers/pincode.manager.ts @@ -1,17 +1,32 @@ import { ipcRenderer } from 'electron' +import { createHash } from 'crypto' import type { IPincodeManager } from '@core/app' export default class PincodeManager implements IPincodeManager { public async set(key: string, pincode: string): Promise { - return ipcRenderer.invoke('keychain-set', key, pincode) + const hash = this.hashValue(key, pincode) + return ipcRenderer.invoke('keychain-set', key, hash) } public async verify(key: string, pincode: string): Promise { - const storedPincode = await ipcRenderer.invoke('keychain-get', key) - return storedPincode === pincode + const hashedPin = this.hashValue(key, pincode) + const storedHash = await ipcRenderer.invoke('keychain-get', key) + if (pincode === storedHash) { + // Set pincode as a hash if it is stored in clear text (legacy implementation) + void this.set(key, pincode) + return true + } else { + return hashedPin === storedHash + } } public async remove(key: string): Promise { return ipcRenderer.invoke('keychain-remove', key) } + + private hashValue(salt: string, value: string): string { + const hash = createHash('sha256') + const hashedValue = hash.update(`${salt}:${value}`).digest('base64') + return hashedValue + } }