Where does the WebCrypto API store keys? - javascript

I am using the webcrypto API with some success to encrypt messages between server and client (lets assume I need to do this manually).
My problem is that I need to check if a keypair for the user and server already exists instead of generating a new keypair all the time. Is there a way to check if it exists and retrieve it for decryption of server messages?
To clarify, my privateKey is on the browser and publicKey is sent to server.
I have a nodejs server and plain JS front end.
Thanks in advance.

CryptoKeys are not persistent by default. You need to store the keys in the IndexedDB to make them available to the next browser execution.
IndexedDB is a secure storage, keys can be stored, recovered and used without exposing the key material
See https://www.w3.org/TR/WebCryptoAPI/#concepts-key-storage
5.2. Key Storage
This specification does not explicitly provide any new storage mechanisms for CryptoKey objects. Instead, by allowing the CryptoKey to be used with the structured clone algorithm, any existing or future web storage mechanisms that support storing structured clonable objects can be used to store CryptoKey objects.
In practice, it is expected that most authors will make use of the Indexed Database API, which allows associative storage of key/value pairs, where the key is some string identifier meaningful to the application, and the value is a CryptoKey object. This allows the storage and retrieval of key material, without ever exposing that key material to the application or the JavaScript environment
Here you have a full example https://blog.engelke.com/2014/09/19/saving-cryptographic-keys-in-the-browser/

SOLVED:
You can use IndexedDB for storing CryptoKey objects.
I tried plain old local storage and it does not work.
For more info, see:
https://pomcor.com/2017/06/02/keys-in-browser/
https://www.w3.org/TR/WebCryptoAPI/
https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API
https://www.w3.org/TR/IndexedDB/
https://www.boxcryptor.com/en/blog/post/building-an-app-with-webcrypto-in-2016/
https://gist.github.com/saulshanabrook/b74984677bccd08b028b30d9968623f5
https://blog.engelke.com/2014/09/19/saving-cryptographic-keys-in-the-browser/

You should Use indexed DB to store Keys on the client side. The benefit of using Indexed DB is that you will be able to store keys as they are (mostly in CryptoKey form) and use them after retrieving from Indexed DB.
You won't have to export keys and then transform in some way like base64 encode or JSON encode as in case of other storage options like LocalStorage.
To make indexedDB usage easier, there is a promise based library available which is very often used by the tutorials and posts that cover indexed DB usage

Related

Is it possible to view secret variable declared in angular in browser, after build and run?

I want to use an a decryption algorithm on the data I receive through REST-API, for that I am storing the secret-key in angular component ts file.
I want to know that after I build and deploy the code. Will my secret key be visible somewhere in the browser, because the built code is pure javascript which is fetched by server.
I am using crypto-js library for decryption of data.
var secret_key = "super-secret";
CryptoJS.AES.decrypt(ciphertext, secret_key)
If you can explain the situation why you need it, may be a chance you can get better way to do it.
There are 3 different ways to achieve it :-
Pass roles/permissions to local storage as well as same time put into session table(or any other table) in backend. Check role/permission every time user request for something to make sure it is not modified.
Store the roles/permission in backend e.g in session table and then provide roles/permission on every request. This way you do not have to worry about any modification by user anytime.
Pass the encrypted (RSA algorithm)roles/permission in cookies and make cookie httpOnly true and secure true, these cookies cannot be accessed/modified as per protocol and then in each request you will have
The best practice here is to execute encrypt/decrypt operation on backend (server-side) and get the decrypted value from you API
Yes it will be visible to individuals looking for it. You should never store secrets in any client-side code.
The key should be acquired from a server once the client authenticates.
Good post on key storage options
https://pomcor.com/2017/06/02/keys-in-browser/
Section 5.2 of WebCryptoAPI discusses a bit about key storage
https://www.w3.org/TR/WebCryptoAPI/

Can we store files in Chrome Storage, instead of strings

I could read in the Chrome storage API page that we can store string values inside Chrome storage against keys. Is there any way to store files against keys inside Chrome storage?
chrome.storage stores data as the JSON stringification of the values which it's given to store. So, yes, if you convert your file(s) into a form that can be converted to JSON (e.g. by JSON.stringify()), then the contents of the file can be stored. If the value that you are trying to store in chrome.storage can not be converted to JSON, then it can't be stored (e.g. DOM elements). chrome.storage does not inherently care what the data represents, only that it can be JSON stringified.
If you're asking, as stated in your comment, if it's a good idea to store thousands of different "files" totaling more than 5GB in chrome.storage, then the answer is: "NO!".
If you are looking for alternatives, then some are provided in Can you use HTML5 local storage to store a file? If not, how?

Architecture for temporary storing of values within a javascript library

I am currently writing a javascript library that wraps a REST API provided by a third party (intended to be used on server side, but wouldn't like to limit it to). One of the actions defined by the api is 'login' which gives me a session key that I need to use on further requests. Currently, everytime I go to use this library I need to login again as there is no persistence of this session key. My question is, what is the best way to persist it throughout a session?
My first instinct was to give the library a callback that would store it and a callback that would retrieve it and the implementation can determine how that session key is persisted:
var thirdPartyApi = new ThirdPartyApi({
loginCredentials: {..},
setSessionKeyCallback: function() {},
getSessionKeyCallback: function() {}
});
thirdPartyApi.makeSomeRequest('foo');
Can you recommend the best architecture for this problem?
It seems like you want to use the REST Api in a browser. There are some factors you need to take into account, such as, navigating away from the page and coming back to it later.
You can use Web Storage to store the key. There are two types, localStorage and sessionStorage. The only difference between then is that sessionStorage is deleted when the browser window is closed, while localStorage isn't. Web Storage is supported by all modern browsers and IE8+ http://www.w3schools.com/html/html5_webstorage.asp
The localStorage object can be used as such:
localStorage.setItem("bar", foo);
var foo = localStorage.getItem("bar");
localStorage.removeItem("bar");
sessionStorage object can be used the same way.
both localStorage and sessionStorage are global objects that can be accessed from anywhere, so there is no need for any special architecture on your ThirdPartyApi object.

titanium appcelerator data storeage for newspaper/magazin

I want to develop app for viewing newspaper/magazine using Titanium Appcelerator, and I have a problem how to store data on phone that user can't access it other way than by app ? what format should that data have (blob, pdf, plain text) ? should they be stored in db, or as a files ? Can You post your suggestions below, please ?
In Titanium you have several options to store data. First you should check the data you get as input. Is it JSON or PDF or plain text or whatever.
Following options are available:
- store data using integrated databases (SQLite) - this might be appropriate when your input data is plain text or json that can converted to text or something like that. You can also store blob data in database if you want.
- store data using file system: on both iOS and Android (not mobileweb i think) you can store data persistent on the file storage. This is useful if your input data is a binary file (pdf or similar).
However in both cases the user is able and not able to read data.
- iOS: The User will be able to read documents persisted on the filesystem and maybe also data located in the database
- Android: i think on android this depends on whether the device has root access or not and where you store that data (within app folders or in external / internal but free accessible storage)
In both cases it's not easy to access this data. Usually a common user won't do that. For a professional user reading this data should be easy. So how can you secure this data, so that the user is not able to read it?
Either you store the data encrypted in a database (database encryption is not available in titanium by default so you need to use a module or encrypt data on your own) or you store it encrypted (this is also up to you - there is no ready-to-use method) on the filesystem.
In my opinion the first solution is the better one. I would do the following:
- get data (from the server or elsewhere, data type doesn't matter)
- convert to base64 (useful & required for binary files but also for plain text)
- encrypt base64 with an encryption algorithm of your choice
- store in database
because this can require much memory you should provide the option to remove this data to save space.

Local storage and JSON

Where are the data stored in local storage? Is it in form of some text or ASCII format or some other? Is it possible to store JSON data in text files (which can be regularly) updated and retrieve them back? I want to store some JSON data but since my requirement is not so big, I want to abstain from using a database for now.
Local storage can only store strings (any data you might have, have to be converted to string upon saving in storage and "revived" upon reading from it).
JSON data is more than fine to be stored as a string so it is good choice of format for keeping complex data in browser storage (either local storage or session storage).
You can learn more about storage here: http://diveintohtml5.info/storage.html
As to where the data is being stored, I imagine it varies from browser to browser but you don't have to worry about where is the data, since you don't have any direct access to it (only through storage API).
Edit: Quick note - I've found this article stating where is storage data stored by Firefox - https://developer.mozilla.org/en/DOM/Storage (see section "Storage location and clearing the data" at the bottom of the page).
I wrote a tiny script to allow storage, and reading of arrays, strings, and objects into local storage. IT even lets you modify nested keys within the objects you store. Here is a link to the tiny script. https://github.com/andresgallo/truStorage/blob/master/truStorage.js
Getting:
const got = JSON.parse(localStorage.getItem('my-key'));
Setting:
localStorage.setItem('my-key', JSON.stringify({ a: 'A' }));

Categories

Resources