I want to encrypt file before storing into IPFS network so that only person who is uploading a file should be able to decrypt.

closed as off-topic by smarx, Achala Dissanayake, Lauri Peltonen, Ismael, eth Aug 26 '18 at 5:54

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "This question does not appear to be about Ethereum, the decentralized application platform and smart contract enabled blockchain, within the scope defined in the help center." – smarx, Achala Dissanayake, Lauri Peltonen, Ismael, eth
If this question can be reworded to fit the rules in the help center, please edit the question.


You can use the public key to encrypt it so that only the private key can decrypt it.

I wrote this based on npmjs/eth-crypto, it takes the user's ethereum keypair. It's not super optimal but it will work. Ideally you'd want people to have a second key pair derived from the same seed but ECDH.


  • ECDSA is a digital signature algorithm
  • ECIES is an Integrated Encryption scheme
  • ECDH is a key secure key exchange algorithm

You could also have the user encrypt it on the client through AES.

import {publicKeyConvert} from 'secp256k1'
import {encrypt, decrypt} from 'eccrypto'

* @method encryptMessage - Encrypted a signed message
* @param {Object} payload - Stringified JSON object containing the message and optional signature
* @param {Object} wallet - Wallet (public Key) to encrypt message with
* @returns {Object} - Object with encrypted values as hex
const encryptMessage = async (payload, wallet) => {
  return await encryptWithPublicKey(wallet.publicKey, payload)

    * @method decryptMessage - Decrypt an encrypted credential/message
    * @param {Object} encryptedPayload - Object with the encrypted credentials
    * @param {wallet} wallet - Wallet containing the privatekey associated with the publickey the message was encrypted with
    * @returns {Object} - Object containing the decrypted values
    const decryptMessage = async (encryptedPayload, wallet) => await decryptWithPrivateKey(wallet.privateKey, encryptedPayload)

* @method encryptWithPublicKey
* @param {String} pubKey - Compressed 33byte public key starting with 03 or 02
* @param {Object} message - message object to encrypt
* @returns {String} - Stringified cipher
function encryptWithPublicKey(pubKey, message) {
    pubKey = pubKey.substring(2)
    pubKey = publicKeyConvert(new Buffer(pubKey, 'hex'), false).toString('hex')
    pubKey = new Buffer(pubKey, 'hex')
    return encrypt(
    ).then(encryptedBuffers => {
        const cipher = {
            iv: encryptedBuffers.iv.toString('hex'),
            ephemPublicKey: encryptedBuffers.ephemPublicKey.toString('hex'),
            ciphertext: encryptedBuffers.ciphertext.toString('hex'),
            mac: encryptedBuffers.mac.toString('hex')
        // use compressed key because it's smaller
        const compressedKey = publicKeyConvert(new Buffer(cipher.ephemPublicKey, 'hex'), true).toString('hex')

        const ret = Buffer.concat([
            new Buffer(cipher.iv, 'hex'), // 16bit
            new Buffer(compressedKey, 'hex'), // 33bit
            new Buffer(cipher.mac, 'hex'), // 32bit
            new Buffer(cipher.ciphertext, 'hex') // var bit

        return ret

* @method decryptWithPrivateKey decript an EC publicKey encrypted message with the associated private key
* @param {String} privateKey - the privatekey to decrypt with, including '0x' prefix
* @param {String} encrypted - the stringified cipher to decrypt
* @returns {Object} - the decrypted message

function decryptWithPrivateKey(privateKey, encrypted) {
    const buf = new Buffer(encrypted, 'hex');
    encrypted = {
        iv: buf.toString('hex', 0, 16),
        ephemPublicKey: buf.toString('hex', 16, 49),
        mac: buf.toString('hex', 49, 81),
        ciphertext: buf.toString('hex', 81, buf.length)
    // decompress publicKey
    encrypted.ephemPublicKey = publicKeyConvert(new Buffer(encrypted.ephemPublicKey, 'hex'), false).toString('hex')
    const twoStripped = privateKey.substring(2)
    const encryptedBuffer = {
        iv: new Buffer(encrypted.iv, 'hex'),
        ephemPublicKey: new Buffer(encrypted.ephemPublicKey, 'hex'),
        ciphertext: new Buffer(encrypted.ciphertext, 'hex'),
        mac: new Buffer(encrypted.mac, 'hex')
    return decrypt(
        new Buffer(twoStripped, 'hex'),
    ).then(decryptedBuffer => decryptedBuffer.toString());

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