6

I Have an use case where i need :

1- My data not to be visible to the public.

2- To be able to revoke my clients/users rights to view said data from my smart contract.

As anyone done that before ?

I was thinking of encrypting / decrypting my data client side so that the data is never visible on the blockchain in clear and that seems solid enough.(client would hold the private key)

But then i'm failing to see how to prevent my users from watching the events for that contract using something like

contractInstance.EventName({x: y}, {fromBlock: 0, toBlock: 'latest'});

or by calling getters directly form their local node when i want to revoke their right to see it.

I was thinking of re-encrypting the data On blockchain a second time and have my contract decrypt it for address in some kind of list , but that would require my contract to hold the private key and that would effectively make everything useless.

Are there any solution other / better solution to this issue?

Edit :

A bit more on my usecase it a kind of registry. I'm hosting data on the blockchain , i give the right to add/edit data to my users with basics rights (i'm owner of the contract and there is a list of authorized user that can use add/edit functions).Also,User can edit his own data only but can see the whole set, if subscribed.

I want that same list of user ONLY to be able to read the data ( subscription based system ) so that once the subscription runs out they can't event read the data anymore.

I'm having a hard time picturing the proper design as encrypting the data and sending it to the blockchain while having the private key stored in my privately distributed client is fine,but that would still mean the client hold the key to decrypt the data forever. Or i would have to re encrypt the whole set of data each time a client unsub which is not realistic.

2 Answers 2

6

You cannot prevent anyone with access to the blockchain from reading state and executing code in any way they wish. You can encrypt data, but that doesn't prevent people from seeing it, just interpreting it.

Assuming you're happy with people who have stopped subscribing being able to access the data that was already available to them - something you fundamentally can't prevent anyway - there are a couple of ways you could achieve this.

One is to use standard multi-recipient public key encryption: Encrypt each message with a randomly generated key, then encrypt that key with the public key of each user who should be able to access it. When a user ceases their subscription, remove them from the set of active keys. When a new user subscribes, add them to the set, and encrypt the secrets of any past messages they should be able to access.

A slight variation may permit easier key management: Use one key for each 'epoch'. An epoch ends each time a user ends their subscription. Whenever you insert a message, encrypt it using the current epoch key (make sure to use an IV too, to prevent dictionary and known-plaintext attacks). Provide a keystore that lets users access the epoch keys for every epoch they're subscribed to; either off-chain, or by encrypting those keys with the public key of each user who's permitted to use them.

8
  • @jayD Based on your edit, you could get a public key from each customer, and encrypt the data with each active user's key when it's published. If a user ceases their subscription, you can remove their key from the active set; they'll only be able to access data up to when their subscription terminated. Commented Apr 20, 2016 at 10:47
  • But wouldn't that mean having the whole data set stored n^activeuserkey times ? because i can't picture how would the user be able to see the whole set of data if it's encrypted using different private keys? am i missing something
    – jayD
    Commented Apr 20, 2016 at 11:04
  • @jayD You can encrypt each message with a randomly generated key, then encrypt the key with each of the users' public keys. This is actually how regular public key encryption works anyway. And the overhead is n * activeUsers, not n^activeUsers. Commented Apr 20, 2016 at 12:22
  • I've updated my answer with more detail to this effect. Commented Apr 20, 2016 at 12:33
  • Great that's perfect! could you just point me in the direction on how to " encrypting those keys with the public key of each user who's permitted to use them" . I understand how that might be done client side but i'm more looking for on On chain solution if possible. Is there a way in solidity to encrypt data from a function param using a list of address so that for each data added i can encrypt the auto generated key for each user/address ?
    – jayD
    Commented Apr 20, 2016 at 13:24
0

Have a look into Quorum. It runs 'over' a Ethereum network and mostly does what you are talking about.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.