Reputation: 86230
Localstorage is stored without any protection. Web apps are becoming less dependant on servers.
How can an app which uses localstorage for data store it so that a password is required to read it.
Upvotes: 1
Views: 4631
Reputation: 86230
Passwords on servers usually work by using a hash like SHA1 or SHA512. When the server receives a request with a password, it hashes that, and compares them. If they match, the server loads some data, processes it, and sends it back to the user. If we tried to do this with client-side JavaScript, we would have to already have the plain text available.
An alternative to hashing is a cipher, such as AES. There's a crypto-js library on Google which provides services like these. The stand-alone minified AES file is about 13kb before gzip.
One limitation of the library is JSON serialization of the AES data. Their documentation, does provide a solution to this.
Note: this doesn't JSON encode your object, it JSON encodes the data needed to decrypt your object (except the password, of course).
var JsonFormatter = {
stringify: function (cipherParams) {
var jsonObj = {ct: cipherParams.ciphertext.toString(CryptoJS.enc.Base64)};
if (cipherParams.iv) {jsonObj.iv = cipherParams.iv.toString();}
if (cipherParams.salt) {jsonObj.s = cipherParams.salt.toString();}
return JSON.stringify(jsonObj);
},
parse: function (jsonStr) {
var jsonObj = JSON.parse(jsonStr);
var cipherParams = CryptoJS.lib.CipherParams.create({
ciphertext: CryptoJS.enc.Base64.parse(jsonObj.ct)
});
if (jsonObj.iv) {cipherParams.iv = CryptoJS.enc.Hex.parse(jsonObj.iv)}
if (jsonObj.s) {cipherParams.salt = CryptoJS.enc.Hex.parse(jsonObj.s)}
return cipherParams;
}
};
To store data, we could do this
var encoded = CryptoJS.AES.encrypt(JSON.stringify(data), password, {format: JsonFormatter}).ciphertext.toString();
localStorage.setItem("secret_stuff", encoded);
To get it back, we can do:
var stored = localStorage.getItem("secret_stuff");
var jsonString = CryptoJS.AES.decrypt(stored, password, {formatter: JsonFormatter}).toString();
var secretObject = JSON.parse(jsonString);
It might also be wise to "forget" the user's password if they haven't moved the mouse in a few minutes.
Upvotes: 5