I have developed a customizable storage service where an example is
getExpirableStorage(getSecureStorage(getLocalStorage() | getSessionStorage()))
in typescript/javascript.
When implementing getSecureStorage
, I used a static cipher key to encrypt every key/value pair added to local or session storage.
To enhance security, I decided to generate a new key dynamically after each expiration to prevent potential sharing of the key by users who may access it from the source. This approach requires storing a new cipher key for each unique key/value pair.
createSecureStorage(storage: Storage): Storage {
var cipherKeyMap = this.keyMapping;
let privateState = function() {
let cipherKey;
this.encrypt = function(key: string, data: string): string {
let entry = cipherKeyMap.find(entry => entry.key === key);
if (entry) {
cipherKey = entry.cipherKey;
} else {
cipherKey = Array.from({length: 16}, () => Math.floor(Math.random() * 90));
cipherKeyMap.push({"key": key, "cipherKey": cipherKey});
//...
};
this.decrypt = function(key: string, data: string): string {
//...
};
}
let state = new privateState();
return {
setItem(key: string, value: string) {
//...
},
getItem(key: string) {
//...
},
//is triggered from expirableSecureStorage
removeItem(key: string) {
storage.removeItem(key);
cipherKeyMap.splice(cipherKeyMap.findIndex(r => r.key === key), 1);
}
}
}
This function is applicable for both localStorage
and sessionStorage
which are of type Storage
and also exported as
//lib.dom.d.ts
declare var sessionStorage: Storage;
declare var localStorage: Storage;
This service will be utilized by multiple clients for storing values in these storage facilities.
During the implementation of the createSecureStorage
function, I realized that if the passed storage is localStorage
, the user's closure of the tab/window would result in wiping out the application state and losing the cipher keys while the related data remains encrypted with those keys in local storage.
Considering this situation, I have two options:
- Manage the persistence or clearance of randomly generated cipher keys in case of localStorage.
- Store only values encrypted with a static cipher key in localStorage and store the remaining values encrypted by dynamically generated keys in sessionStorage.
I opted for #2 to avoid persisting the cipher keys on the client side due to current security concerns.
In order to differentiate between sessionStorage and localStorage, how can I achieve this?