Skip to content

Keystore/encryption/ipfs usecase for a file-sharing application #3866

@MichaelMure

Description

@MichaelMure

As asked by @whyrusleeping, here is my usecase for ipfs and in particular for the keystore/encryption feature.

I'm building a file sharing application presented as a social network. The main target is friend to friend sharing (think holiday pictures) with a control on who has access to the data by using encryption. The underlying goal is to reduce the need to use solution like Facebook, Dropbox, Drive... for data exchange that should be kept private and to create a better solution.

The project is here (no readme, sorry, I should do that). The tech stack is electron, react, redux, ipfs-connector --> js-ipfs-api --> go-ipfs. I'm working on it full-time and hope to have a first (crippled) version in 1-2 months (there is no chance I'll regret having said that in the future, right ? ;) )

What is described below is a general plan and not fully figured out.

Identity

I don't use a central authority like an identity server or a blockchain. As the target is a friend-to-friend network, I chose to have identity simply being a crypto keypair (ipfs key gen with a passphrase) and to build a trust network contact-list for each user. Login in the application will be selecting a profile and entering the passphrase to unlock the private key. Each user publish a profile in his IPNS namespace (ipfs name publish --key mykey), including his public key. I guess it's a good idea to also sign this data (ipfs crypt sign).

Contact management

Each user will have a contact list with the keys stored in the keystore. Contact can be added 'manually' by entering the public key hash of the contact. The profile is then resolved on IPNS (ipfs name resolve contact-hash), fetched, verified (ipfs crypt verify) and imported in the application. I need a way to import the public key in the keystore (MISSING). As both user are not necessarily online at the same time ipfs key send will not do as it is a push. I need a pull version from the profile data.

Users share their contact list with their contact (with some privacy settings). That mean that once the first contact is added, the application can build a suggestion list for the user to easily add new contacts and build his social graph. The same way as before, the profile is retrieved from ipfs and stored locally.

Sharing and encryption

There is 3 kind of sharing. The first second version (I guess the first version will have no encryption at all) will only provide only the targeted sharing.

When a user share something, the data is added to the IPFS repo (using the no-copy filestore ❤️). Metadata are stored as well and a notification is sent using pubsub (ipfs pubsub pub contact-hash share-hash).

Targeted sharing (main priority)

Users can share with a set of specific contact. In this case the data should be encrypted with a generated key that is then encrypted for each recipient public key and added as metadata of the share. As far as I can tell this is not possible with the current encryption spec (MISSING)

The root is also signed by the author (ipfs crypt sign/verify).

Public sharing

Users can share for anyone interested and follow public identity. In this case the data don't really need to be encrypted (?), but the root should be signed (ipfs crypt sign/verify) with the author's key.

Private sharing

User can duplicate their identity on several node and share files to themselves to have kind of private repository of data or synchronization tool. Not really a priority but could be nice. In this case, the data is encrypted using the own author keys and signed.

Relax the online constraint

To relax the constraint of having both user online at the same time for them to communicate, contacts could help each others (they are friends, right ?). That include:

  • keeping online contact's profiles (ipfs pin) and profiles ipns record (just a long ipns ttl set by the author)
  • keeping online share notification
  • keeping online share data using an allocated disk space

Another way would be to use a commercial pinner.

Tracking the download progress

While I'm at it, I need a way to track the progress of a download (MISSING). That means:

  • completion event (file added/removed)
  • progress event (for the root hash or each file in the tree)
  • speed event (how much bandwidth contribute to the progress)

This can partially done by retrieving the file graph using ipfs ls and ipfs refs --recursive and then polling ipfs refs local but it's very inefficient and could easily destroy the performance with big repository.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions