This question is about combining IPFS with Ethereum smart contracts to check conditions and encryption to restrict access.

One-on-one file sharing with a known recipient is not an issue. The 'sender' would encrypt the file with the recipient pubkey, upload it to IPFS send the hash to the recipient. The recipient could then decrypt the file with his privkey.

My issue occurs when dealing with (multiple) unknown parties. If we combine IPFS hashes with Ethereum we could for example transfer the IPFS hash to a recipient that wants to access it and decrypt it once certain conditions have been met eg. a payment has been made. These recipients are thus not known beforehand, we can not encrypt the file with the pubkey of the recipient.

We can not simply store the decryption key on the ethereum blockchain, this key would be visible to anyone and thus people would be able to access the encrypted file on IPFS without eg. payment.

One solution is to save the decryption keys that belong to their assets on a seperate centralized datastore, making a single point of failure for our dApp yet again possible.

So I'm wondering if there are any solutions to solve this problem like safely storing the decryption keys on-chain.

Many thanks.

  • So the problem is: Alice wants to buy a file from Bob. Bob stores the IPFS directory in the blockchain (somehow encrypted) and then when Alice pays the smart contract she gets the directory of the IPFS address for the file?
    – davinci26
    Commented Mar 25, 2018 at 21:26
  • I second @davinci26's request. Can you elaborate on the "condition"? Precisely what do you want the smart contract to govern? What are the conditions for disclosure or release of the information? Commented Mar 25, 2018 at 21:59
  • Condition: A boolean true or false. eg hasPaid true / hasPaid false The problem is Random people want to buy a file from Bob. Bob stores the file on IPFS (encrypted) , whenever someone buys access they get a decryption key and the client app decrypts and shows the file. I've read about Attribute-based-encryption but not sure that's what I need.
    – Nico
    Commented Mar 26, 2018 at 1:20
  • In that case, each payment could generate a unique identifier. A backend component then takes that identifier, and hashes it together with a randomly produced value. That random value is then encrypted with the payers public ethereum address, and that data is then included in a transaction to the recipient, encoding the encrypted value into the data field of a transaction. The recipient can then decrypt that data safely. To decrypt the encrypted file, the recipient must provide the proper values to reproduce the encrypted hash, successfully downloading the ifle.
    – hextet
    Commented Mar 26, 2018 at 2:29
  • @hextet I don't think the OP is open to use a backend component, that not only makes the system centralised and generally you don't need Blockchain then.
    – niksmac
    Commented Mar 26, 2018 at 3:31

5 Answers 5


Have you checked out Shamir's Secret Sharing algorithm? You could use IPFS to share the secrets between all parties, and use each other's ethereum public keys to send encrypted communications to each other.


If you don't absolutely need to use the main ethereum chain, you could construct a private quorum blockchain between the parties https://www.jpmorgan.com/global/Quorum using secret contracts.


You should look at proxy re-encryption and Nucypher.

Essentially how this works is you create a random key and encrypt your data with that key. You then encrypt the key with your public key. and prepend this encrypted key to your data. If you then want to give Bob access to the data you create a re-encryption key using his public key and your private key. You then send this re-encryption key to some proxy service. Bob can then send the encrypted decryption key that he got from the beginning of the file, to the proxy service. The proxy will re-encrypt the key using the re-encryption key. This re-encrypted key will allow Bob and only Bob to decrypt the key. Once the key is decrypted Bob can use the decrypted key to decrypt the data of the file.

  • This looks like a neat solution, thanks for posting. I'll look into it rather soon as we're building a PoC. Thank you !
    – Nico
    Commented May 18, 2018 at 17:21

I would bet that it would be extremely hard to do that with Ethereum. With that said there are the following options that you can check out:

  1. Filecoin which is a blockchain on top of IPFS implements this kind of service and it also supports smart contracts. As far as I am aware there is no implementation yet but the whitepaper is out. Source
  2. You can see openbazzar solution that uses trust graphs to solve this kind of problem. Source

Neither 1 nor 2 is an exact solution to your problem but it could be a starting point for discussion.


Bob can store decryption key encrypted with his public key onto blockchain, so when Alice comes with condition that she has paid, bob reads encrypted decryption key from blockchain, decrypts it and again encrypt it with Alice’s public key to store onto blockchain. Which whenever Alice requires can decrypt it with her private key.

  • this seems to be the most easy solution propsed so far, I'll try to test it out one of the cominng days.
    – Nico
    Commented Mar 31, 2018 at 16:59
  • So to clarify: 1. Bob stores on the BC the encryption key of the file (denoted k) as enc(k, pk_bob). 2. Alice pays sends the payment 3. The smart contract hold the payment until Bob sends enc(k, pk_alice) to the blockchain If this is the algorithm then bob can cheat and not send the decryption key in the third step. Is there a mechanism that ensures the relation between enc(m, pk_bob) and enc(m, pk_alice) in an asymmetric encryption scheme?
    – davinci26
    Commented Apr 1, 2018 at 15:13
  • As this depends on how he has designed smart contract, there should be some escrow account, if someone cheats. Even if bob encrypts enc(k, pk_alice) , what if encryption key provided by bob is wrong, or even file contents are not as desired by alice? @Nico could answer these inner workings.
    – kherwa
    Commented Apr 1, 2018 at 15:55

Encrypting media files in general take a lot of compute and storage and overall time and gas. But indeed in light of what @Kherwa said; you can use Alice's public key to encrypt the file and store it on IPFS. However this will limit the media to a single wallet, using ERC721 non-fungible tokens could do the same for you, but with added flexibility.

In the first situation you need to know when the media encryption process is done and preferably want the IPFS url to be stored somewhere with the smart contract and the associated wallet for later retrieval. I recommend you use an action based multi contract architecture that waits after the payment is done for your etherium oracle to callback when the encryption process is over and send you the details of the IPFS location. You can then store that data in the contracts transaction so that Alice can retrieve her media at whenever, where ever. I believe this is to be a regular secure method, since people do not tend to give away their private keys aka their wallet. The possible risk in this method could be that someone publishes his or her private key and everyone can access the content. To stop that kind of abuse one could couple KYC to the wallet before the encryption process starts.

In the case of a non-fungible token, the situation is different. An ERC721 token could represent a product with an unique id. That unique id represents a shared secret to the content in order to prevent the whole secret be known and with it abuse. The benefit in all this is that the product can be transferred to another wallet, allowing the new owner to access the content. This would be very useful for many different applications, including hardware of all sorts. I'm not sure how this could be implemented on IPFS at the moment and if there is any sort of witness needed to make the shared secret work. Although, I'm still wrapping my head around this on how to implement such system, I see a lot of potential. However don't take it to seriously.

In both cases the real problem lies in the end node when the data of the media file or product, if you will, is decrypted and cached for playback. Any client that knows how to deal with this kind of encryption and is allowed to use the private key is in a sense capable of copying the media and distribute it off-chain and sight anywhere they like. I believe therefor that the most reasonable option is live streaming media with a kind of subscription structure attached to it or people looking for private content of some sort.

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.