0

I have an app where a users' device create a public/private key and all communication to this user is done by encrypting against their public key, which is stored on a server and sent to other clients that request it.

Now I'm trying to make it so that this works across multiple devices.

I'm thinking I can just have the new device generate a key pair ("temp key"), encrypt the user's private key against the new device's public key, send it to the new device, and wipe out the "temp key".

Are there any issues with this? Is there a better solution that doesn't require sending new versions of the public key to everyone that already has it?

None
  • 1
  • 3
  • 7
  • Depending on your trust model, why not flip the keys around? Store the private key on your server and distribute the public keys to the user's devices upon proper authentication? – schroeder Sep 07 '15 at 15:59
  • How do you know that the "new device" is legitimate? Do you need the ability to transfer the key in time, or is an interactive protocol acceptable? – user Nov 06 '15 at 13:48
  • @MichaelKjörling -- The device will need to log in first, so whatever auth (1/2 factor) we end up using there. I'm not sure what you mean by "in time"? I'd be okay with requiring user input at both devices at the same time. – None Nov 06 '15 at 14:02
  • By "transfer the key in time" I meant to for example make a secured copy of the key that can be *later* reinstalled on a different device, for example as a backup copy. – user Nov 06 '15 at 14:26
  • @MichaelKjörling -- One of the primary purposes for this is to be able to say "We (as a company) have absolutely no way of decrypting your communications", so that's a no-go. It needs to be device-to-device, or encrypted with the private key of a device, etc. – None Nov 06 '15 at 14:33

3 Answers3

1

One of the primary purposes for this is to be able to say "We (as a company) have absolutely no way of decrypting your communications", so that's a no-go. It needs to be device-to-device, or encrypted with the private key of a device, etc.

Well, in that case, we have established that both devices must be able to communicate with each other, bidirectionally and in real time, in order to complete the transfer.

In that case, there is really no need for elaborate public-key encryption schemes. In fact, they are more likely to introduce problems.

We also know that lots of people aren't really prepared to physically destroy media, have the capability to do so securely, or even understand why it might be important to do so. Instead, most people tend to just delete the file through the OS, leaving all of the data intact on the media for anyone who comes around to look. So M'vy's suggestion of letting the user copy the key onto media they have physical control over, while good in theory, isn't really a great idea in practice.

Instead, use a key exchange algorithm such as Diffie-Hellman Key Exchange (Wikipedia, RFC 2631) to allow the two devices involved to interactively agree on a shared secret. Since we don't want to reinvent the wheel, use whatever TLS or perhaps SSH/SFTP/SCP libraries are available for your target platform to do the heavy lifting. (Generally speaking, never write crypto code yourself. Odds are great that you will get it wrong, introduce subtle bugs, and leave your users' data at risk of exposure. Let someone else make those mistakes.)

Although unrelated to the cryptography itself, make sure this process involves the user authenticating on both devices in some manner.

Once the two devices have agreed on a shared secret consisting of, say, 32 random bytes, use that shared secret as a symmetric encryption key. AES-256 is good enough for most purposes these days, the 256-bit key having the added benefit of providing a safety margin also in a post-quantum cryptography world, and for a given work factor AES is not very computationally intensive.

Once you have transferred the long-term key from one device to the other and verified that the copy is good, just wipe the temporary encryption keys from both devices and possibly wipe the long-term key from the device it was transferred from (this last is likely to be your biggest problem).

user
  • 7,700
  • 2
  • 30
  • 54
0

The Diffie-Hellman key-exchange protocol can easily be extended to work with three or more people. See http://mathworld.wolfram.com/Diffie-HellmanProtocol.html and Schneier Applied Cryptography Chapter 22 - I think page 510.

Schneier also describes Key Exchange without Exchanging Keys

If you have a community of users, each could publish a public key, X = g x mod n, in a common database. If Alice wants to communicate with Bob, she just has to retrieve Bob’s public key and generate their shared secret key. She could then encrypt a message with that key and send it to Bob. Bob would retrieve Alice’s public key to generate the shared secret key. Each pair of users would have a unique secret key, and no prior communication between users is required. The public keys have to be certified to prevent spoofing attacks and should be changed regularly, but otherwise this is a pretty clever idea.

Danny Lieberman
  • 388
  • 2
  • 6
  • Yes, the problem I have with this is that it would require either a device<->device key, or a new user public key every time that user added a new device. Am I wrong? – None Sep 07 '15 at 13:54
0

The best way to transfer private keys is for the owner to copy the key to a medium he has full control over.

If you need to ensure protection for the loss of the medium, any encryption system can be used, whether it is USB key encryption, embedding the key in a PKCS#12 container , or crypt the file. This is basically one of the job of keystores.

M'vy
  • 13,053
  • 3
  • 48
  • 69
  • This doesn't really answer my question, unfortunately. I'm trying to get the same keys on multiple devices owned by the same user. Two phones, phone+laptop, whatever. Telling them to use a USB key is a non-starter, it needs to be transparent. – None Sep 07 '15 at 13:55
  • Can you copy the keys with SSH? Would the strategy used for ssh public keys work for you? You are probably familiar with SSH public keys but I would think about copying the flow described here https://help.github.com/articles/generating-ssh-keys/ – Danny Lieberman Sep 08 '15 at 12:13