1

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.

0

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.

https://crypto.stackexchange.com/questions/12823/ecdsa-vs-ecies-vs-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(
        pubKey,
        Buffer(message)
    ).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
        ]).toString('hex')

        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'),
        encryptedBuffer
    ).then(decryptedBuffer => decryptedBuffer.toString());
}

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