I'm working at a crypto wallet extension for a startup and currently we are facing the issue of storing private keys after we generate them from a mnemonic phrase. I was thinking about storing those password in the local localStorage as an encrypted format using AES but this doesn't seems to be good enough.
I was also thinking about using the chrome.storage but this one seems to have the same issue of not being secured.
As for the chrome.filesystem this one is deprecated.
If anyone has an idea of how we could store private keys safely on the user's machine please let me know.
Related
I am thinking about storing secret in blockchain. Although there is some specific blockchain dealing with it, I would like to see the feasibility in ethereum.
The idea is to store the secret as a state variable in encrypted format and the accessibility of this variable value is restricted to someone only. My question is, since blockchain is open and everyone, if someone is really skillful then he/she could read the value of the every variable. Do you think, or what is needed to do further, to make the value of the state variable secured enough?
People who own the machine running an EVM full node will have access to that variable. That accessibility limit is pointless in regards of keeping the data secret.
You could store encrypted data on-chain. But you need to keep the decryptor off-chain. E.g. you AES-encrypt a piece of data and post it on-chain, but you keep hold to the private key.
I should point out that an ethereum wallet, aka a secp256k1 keypair is capable of data en/decryption. You can encrypt data using public key, post it on-chain, and later fetch then decrypt with your private key, which is of course off-chain. Read more here.
I am currently working on a project with a lot of security and I am having a bit of a problem choosing a technical solution to satisfy my customer need.
First things first, let me explain you the customer need.
For my customer's website, at some point a user needs to generate a private key and public key client side (gui : browser) then send the public key to the server and save the private key (crypted by a user choosen password) locally. The private key needs to be saved because it is used once in a second part of the process (the user needs to enter his password in order to decrypt it), once used we can dispose of the private key.
I have to add that the customer requests backward compatibility to IE7.
First technical choice : Java Applet
The first thing we looked up is to use a Java Applet, generates the keys just fine, but we enconter a problem on Safari Mac OSX, the appet is sandboxed and the user needs to perform a complicated action to disable sandbox mod. Our customer does not want this as it is not user firendly.
Second solution : Saving crypted private key in a cookie
We kept the java applet, but it does not save anything on disk, it is only used to perform cryptographic actions. We passed from the applet a crypted private key to the javascript to save in a cookie. We did it fine and we can retrieve the crypted private key from the cookie store and pass it to the applet to decrypt (with a popup requesting the user to enter his password).
Question
We know that it is technically doable to save a crypted private key in a cookie, but the question is : is it secured, what kind of risks are we taking saving that private key in a the cookie store of the browser?
It would help me a lot if one of you could help me!
Cheers
The main problem is that cookies are only meant for things you are sending to the server. They are not meant for storage and you should not be sending your private key anywhere, ever.
Cookies can be stolen via XSS (always assume you have an XSS vuln in your site) and the attacker can then try to decrypt it.
On the grand scale of things you could do a lot worse. Assuming your crypto is solid, the private key is probably safe, but the big issue is that you shouldn't be using cookies like this. Using Web Storage is probably a far better solution here.
I´d say that saving your private key in a cookies isn´t a really good choice since they are not supposed to hold sensitive information due security reasons, and our colleagues already told other reasons.
It´s also important to notice that the user may clear all his cookies at any given time or disable it at all.
The applet would meet better your customer requirements and would let you for example prompt the user to save a keystore file with the private key, this kind file was designed to hold this kind of information.
Cookies are sent in each request. This is really really bad because you want the private key to not sent over the network as much as possible.
Assuming you can't have local storage (IE7), the only way I know to store info on the cient side is cookies. I'd say : use local storage as much as possible, and when you can't, store the private key on the server side. At least, you'll be sending it once. it's bad, but less than really really bad ...
Or maybe you could store cookies on a dedicated subdomain that you never use again, but in order to read the cookie, even on the client side with javascript, you need to be on a page of that subdomain, and that means sending the key over the network again everytime you want to use it.
As far as I know.
You could use localstorage then just deploy localstorage polyfill for IE7
In one of my applications, I am to store user credentials and tokens. As the credentials are used directly on third-party services, I cannot hash them and thus need to store them as-is.
As I am not an expert on encryption, I googled and found that AES 256-bit key size-is a good idea to encrypt such data.
I would like to know the opinion of the SO community on the same, before I make a final decision.
Thanks!
Edit: Thanks to all for discussion, I am moving ahead using AES256 as the encryption mechanism for now, which seems like a good choice.
if you ask user for credential every time, then why do you need to store them in db? just keep it in memory and pass to external system. you can even ask user once and keep their password in memory for the whole session. if, for some reason you have to store them in db, them of course encrypt it. as far as i know, current standard is AES256. but still somewhere you have to keep unencrypted key.
to sum up: if you want to authenticate users and then use their password only for the time of session then you don't have to store it in database. keep salted hash for authentication purpose and keep user provided password in session for external systems
btw. is your swap encrypted?
I know how asymmetric cryptography works. I know there are two keys (one private and one public).
When someone wants to communicate they exchange their public keys encrypt messages with those public keys AND then the respective message could be decrypted ONLY by the user that has the private key.
Now, I'm using Node.js and I need to do something like this...
I need an application that EACH hour reads a database, extracts data and saves it to a file that I need to send to another server.
My problem is that I DON'T WANT that file will be visible to other, I do the transfer using SSH so there is no problem BUT
I must encrypt that file because I'm not the admin of that server SO maybe someone could read it. Unfortunately the admin is the same for both servers.
So my idea is to encrypt the file with a public key, and then only he who has the private key(me) could decrypt it.
I think it is pointless using something like:
var key = 'blablabla'
If I use a public key, there is no problem, all can read it..... it is public indeed. But with this public key, nobody can decrypt the message, so it is
something like one-way encryption.
Now, could someone tell me if I need a signer/verifier to do this job, OR maybe I have to generate two keys (public/private) with openssl and pass those keys to a cipher/dechiper?
I'm looking at crypto modules, but there are no examples....
In general, your idea is right - you encrypt using public key and decrypt using private key of yours. However, practically the procedure is more complex. Random symmetric key is generated and the data is encrypted using that key. Then the public key is used to encrypt the random key. Encrypted key is sent to recipient together with encrypted data. On the other side encrypted key is decrypted using a private key, then the data is decrypted.
You can use OpenPGP keys or X.509 certificates to do the job.
In case of OpenPGP the standard offers encryption and decryption as atomic procedures (on the user level). In case of X.509 certificates you need to use PKCS#7 / CMS.
OpenSSL library offers operations with PKCS#7 / CMS, however when I look at nodeJS API for OpenSSL, that API is very limited and doesn't expose those functions. Maybe you can write your own nodeJS module which will interface with OpenSSL and provide missing functions.
Another alternative is to use OpenPGP keys and node-gpg module. That module uses gnupg to do the actual job, so gnupg must be installed.
Unfortunately I don't see any other suitable libraries in the 3rd-party module list provided in nodeJS wiki.
I was thinking about creating a Web app that would let people enter text (using SSL connection) and it would be encrypted before saving to the DB. The goal would be to have it so that only users could decrypt it.
You could have the users enter the key along with their data, and enter it again when they want to see the data, and not store the key. That would be kind of painful for the user, though.
However, if you stored the key on the server you'd have access to it and could potentially decrypt their data.
I don't think it's possible to do it without either having the user enter the key every time or storing the key, but is there some way that I'm not thinking of? Like maybe generating a key from information only the user knows? Something involving cookies?
You should look into public key cryptography. The basic idea is that you can encrypt information using a public key that only the holder of the private key can decrypt. In your scenario, the server would have a record of all the users' public keys and use them to encrypt the information. Then your users would use their private keys, which the server never sees, to decrypt the data.
If you're looking for a way to store the private key client-side, you could look into PersistJS.
Sounds like you could do something using PGP. As a previous post mentioned you would have a public and private key. The private key can be secured by a passphrase. That way you could have the private key potentially stored on the db, since it would still require a passphrase to use it.
The huge problem is that if the user should forget that passphrase, they could lose that data. You could get around that by using an Alternate Decryption Key (ADK). That key is automatically encrypted with everything and can be split between multiple individuals.
From an information security perspective, this only makes sense if the encryption/decryption is done on the user's computer, and not your server (since there's no guarantee that you're not storing the key and/or the plaintext). JavaScript is out of the question, so you need a client application*.
Also, public-key cryptography is computationally expensive. You might want to keep that in mind if you have a lot of users and decide to do encryption/decryption on the server.
* or a Java applet, but that's so 90's. Silverlight or Flash could potentially work, too.