Store Secret in EVM blockchain - security

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.

Related

Store Private Keys Wallet

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.

How to store Encryption Keys while in use

I am making a social media type website, and I store user details such as emails, names and other personal details.
I will be encrypting the personal details using an Encrypt-then-MAC concept. When the user registers, a cryptographically secure string will be made to use as the private encryption key. When the user selects a password, the encryption key will be encrypted using the password.
The password will NOT be stored in the database, but will be the private key to decrypt the encryption key used to encrypt the personal details. The only person who knows the password is the user. My question is: how can I store the encryption key once decrypted?
I have thought of having a table with one column for IP and another column for the encryption key, but some people close the browser window without logging out, therefore there would not a possible way to remove the entry from the database when they have finished their session on the website.
Another way would be to store it in a cookie, but that could be intercepted when sent back to the server. I would like to know if there is a secure, nearly foolproof way to store the encryption key, client side or server side.
Thanks in advance.
EDIT:
In reply to TheGreatContini's answer -
The idea of a "zero-knowledge web application" (in your blog) is a good one, however, for zero-knowledge, even the key cannot be stored in the database, this complicates things a bit, as you would then have to use the user's password as the key. Using the password isn't as secure, as it is a bit harder to verify the password to prevent data which has been "decypted with the wrong key" from passing. There is the concept of Encrypt-then-MAC but that only verifies if the data is legit, and will assume that a hacker has messed with some data and data cannot be trusted, however, as you cannot actually verify the password (the hash would not be stored as it is "zero-knowledge"), so the password may just be wrong.
Not sure I have the answer, but a few considerations:
(1) Sessions need to be timed out. Perhaps you can do this by periodically running batch jobs that scan the database looking for sessions that have lacked activity. This requires storing in the db the date of the last action from the user.
(2) Generally keys are higher value than the content they protect because the keys have a longer lifetime than the individual data elements that the protect (because the data may change or additional data may be added). Rather than storing the key in the db, you can store the decrypted contents in the database for the length of the session. Of course, this is provided that you did (1).
Perhaps I am not adding much beyond what you already know, however may be worth considering a blog I wrote exactly about this topic. The low level details start in the section "A second line of defence for all the sensitive data." Prior to that it mainly motivates the concept. Glad to see somebody actually doing something like this.

decrypt data using master key and not key used for encryption

I am trying to build an application that stores user related information client side in localstorage. I am encrypting that data with a password given by user.
If I implement forgot password and generate a new password how can I get back my data that is encrypted on old password.
I am using sjcl for encrypting data. Is there any technique to encrypt data with 2 passwords??
What would be an ideal pattern for this scenario??
The conventional approach for this is called "key escrow." Basically, it means giving a copy of the key to someone that you trust.
If you won't trust anyone, then key escrow is not for you. Your only option is to make sure that you don't lose the one-and-only key. And this is a fairly common approach too. Many products that advertise secure storage emphasize this point. As examples, see Bruce Schneier's password manager "PasswordSafe," and LaCie's security-focused DropBox alternative, "Wuala."
There are accepted methods for encrypting data so that it could be decrypted with any one of several passwords. But I don't see how this helps; if you can't remember one password, how will you remember two?
Any other approach that pretends to avoid key escrow but still provides a backdoor to access your data if you lose the key is not secure and no one should trust it.

Encrypting text

I'm wondering if it's possible to encrypt text client side.
The situation is that I have a block of text I want to encrypt, and then save the encrypted text to a file. Only after a certain amount of time has passed will my program decrypt it. Another requirement I have is to be able to transfer the file with the encrypted text and be able to decrypt it with other copies of my program on various machines.
The problem is where to store the key. The only implementation I can think of that would work is if I store the key server side, and have it return the key after a certain time has passed.
Is there a way to do this client side (i.e. without any internet access)?
You can surely encrypt text on the client side, but the real problem is key management.
If the assumption is no Internet access, then you're going to have to package a certificate in the client that contains both keys, private to encrypt, public to decrypt, unless you use a symmetric key. Was going to suggest just generating a local, temporary symmetric key, but you state you must be able to decrypt the text on other machines that won't have it, so that won't work. At first blush, and maybe I'm overlooking something obvious, is packaging a cert on the client with public and private keys, and that introduces its own set of problems, eg protecting the cert with the private key.

How could you encrypt user data so only they can decrypt it?

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.

Resources