I am building a web app which uses Sign in with Apple for the normal authorization and login.
After signup the user should create a passphrase which is enhanced via a KDF and acts as a symmetrical key for encrypting all sensible data. Normal operation should look like this:
The clientside storage of this key should be as secure as possible and never be sent to the server - otherwise I as the owner (or an attacker in the system) could decrypt the users database entries.
My first idea was a cookie - save against cross-site scripting, could be set with an expiry data - but the cookie would be sent with every request... And all I heard about all the other local storage alternatives was that they were not secure.
Of course I have the added layer of security with the Apple authorization, but I still would like to store the key as securely as browserly possible. :)
(browserly possible = I want the key to be stored in the browser, protected primarily against remote attacks and automatic expiry would be a nice addon...)
Thank you for your answer!
Hashing of the key is not possible, because I need to retrieve it. Cookies are not possible, because that would automatically send the key with any request. Local Storage is not safe.
I hope someone comes up with a smart solution that I have not thought of yet and maybe helps me with this issue.
The proper question to ask is what does secure mean in the context of your application and what model of interaction with your application is meant to be secure.
Before we start let just make one thing clear. Encryption has never solved any problems for us. It has just shifted the problems somewhere else. You encrypted the plaintext? Great - now you need to protect the key (a lot) and the ciphertext (a little).
You want to have protection from the remote attackers? This is doable and you are already doing it. Encrypting the plain text locally and storing the ciphertext remotely is the way to go.
Now you want to store the key somewhere in the browser. Whom do you want to protect the key from? User, owner of the data? Any person with physical access to the device? Someone capable of accessing binary data on a rooted device? Good luck with that.
You can obfuscate, encrypt the key to get a ciphertext and another key to protect all you want. Even if you create your own hardware, it will not stop motivated attackers from reverse-engineering something they have access to.
To summarize - protection from remote attackers is doable, protection from local attackers is hopeless. Make sure you don't loose your domain, enforce HSTS, do certificate pining... well, don't do it. Even this turned out to be a double-edged sword in the past.