I'm working on an application that'll be used by relatively non tech-savvy users, and while the machines will have internet access, the app can't have any sort of hosted intermediary.

The app allows people to take a file, compresses it down and encodes it as an image for sharing on sites like GitHub to aid in sharing things like test files etc.

The first version of the app works just fine, but sometimes there's data that needs sharing that is sensitive and some level of encryption is called for.

Ideally I want to go down the public / private key pair route, but sharing these is cumbersome and complicated from the user's perspective.

I'd like to be able to (somehow):

  1. Take a user's e-mail address and use this as the public key
  2. Take a password from the user and use this to derive a private key
  3. Entangle these somehow such that they can be used in this manner.

It doesn't really matter if the e-mail address ultimately resolves to something else that is then used, but the general flow needs to be such that:

  1. Alice wants to encrypt an image for use by a particular user
  2. Alice types in the e-mail address of that user (or some other string for the target - e.g. a group)
  3. Bob downloads the image into the app and types in his private password to unpack it.

The app could also sign the data using the private keys for verification on the other side as well.

I know I could use a password-derived public/private key, but that means that the single password could be used to derive both parts, and would make it ultimately useless.

  • You may want to have a look at Wiki: Identity-based encryption. (Which I don't understand at all, but which sounds related.) Commented Sep 22, 2015 at 14:17
  • @StackzOfZtuff yeah, I was recommended that a while back on another site in the network, problem is that is relies on some sort of hosted system to verify identities and provide key pairs. :/
    – Clint
    Commented Sep 22, 2015 at 14:18

2 Answers 2


You cannot use arbitrary strings as private/public key pairs. These needs to be generated according to the math specifics to the PKI algorythm you use (RSA for instance).

You could, however, create an application that uses the same workflow as you described but uses PKI for encryption, as long as you're ready to make some tradeoffs.

First, it starts with a typical asymmetrical encryption (use a standard library please: don't try to code one yourself): you app uses the sender's private key to sign the data and the the receiver's public key to encrypt it. The trouble is that, quite often, you don't have access to a validated public key for the receiver.

To solve that, you have all users generate their own key pair (or pairs) and register the public key(s) on a common platform (a key server). This should include some form of user validation in order to make sure the key really belong to the security principle that is associated with them or you run a risk of someone registering a key with an identifier that doesn't belong to them.

So, when a user needs someone's public key, it can request it from the key server (over an authenticated, encrypted channel) as needed.

Of course, the devil is in the details: building such a system is extremely hard: you need to have a validation system for the keys that is both efficient and practical. Also, you need to take into account the fact that users will routinely lose their own keys, forget their passwords, change their email, etc. The key servers needs also to be extremely secure and, at the same time, operated in a transparent manner because anyone controlling them also control everyone's communication (they could replace any public key by their own more or less transparently).

All these "little" details are extremely hard (and expensive) to solve so unless you have a LOT of resources available, you'll probably be better off with sticking to simple symmetrical crypto.

  • Thanks for this answer, I knew the parts had to adhere to the underlying maths, but I was curious as to whether there was some way to take two arbitrary inputs and then derive the underlying parts, such that it's hidden from the user. This would be a great solution if I could have some intermediary for hosting the public keys, which I can't unfortunately. Symmetric encryption is fine, but then people have got to share / remember the passwords.
    – Clint
    Commented Sep 22, 2015 at 13:55
  • What I might see about doing is have the app auth via GitHub, and shove the public key into a repo against their account. That way addressing would be via their github username. I could then use a password-derived key-pair, such that decrypting and signing only requires typing in the private password.
    – Clint
    Commented Sep 22, 2015 at 13:59
  • For the sharing password issue, you can use a side approach (depending on what you want to do exactly): you use a random key for encrypting the document and encrypt that key with every password that needs to grant access. You can then share the document with several users (you can extend that to make it easier to share documents).
    – Stephane
    Commented Sep 22, 2015 at 14:00
  • that'd be one of way of doing it, and does mean that the overhead of allowing multiple access is smaller as only the key needs encrypting for each target. That does end up losing the easy ability to verify origin though, but might be a small price to pay to avoid having an intermediary.
    – Clint
    Commented Sep 22, 2015 at 14:04
  • 1
    You can't have everything, really. And nothing stops you for incuding a digital signature with your file
    – Stephane
    Commented Sep 22, 2015 at 14:20

Check out my brainkeys experiment. https://github.com/jwilkins/brainkeys

It takes a phrase and turns it into a SSH public/private keypair. Based on the brainwallet concept and code.

  • That's great, but the problem is that the pass derives to both pub and private keys. The public key would still need to be shared independently. (Unless I've misunderstood?)
    – Clint
    Commented Sep 24, 2015 at 7:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .