# How to generate a superkey to decrypt strings

I'm working on an application where users have a key or password generated by me that is used to encrypt a string. Each user has their personal key, and no user should be able to decrypt another user's string.

How to generate a "superkey", which could decrypt the strings encrypted by all the users key? I am new in cryptography, so if I could have a little help.

EDIT : To be more clear :

• Alice encrypts a string with her Key : Ka
• Bob encrypts a string with his Key : Kb
• Alice should be able to decrypt her String
• Bob should be able to decrypt his String
• John, the supersuser, should be able to decrypt Alice and Bob's String
• Why don't you use each user's key to decrypt their string, since you have them? – Graham Hill Jul 25 '14 at 11:35
• @GrahamHill Because I need a superuser (not me) to be able to decrypt all the single user's strings. – Stéphane GROSSMANN Jul 25 '14 at 12:42
• The search term to use is key escrow or master-key cryptography. There's been lots of work on this. (See also identity-based encryption.) – D.W. Jul 25 '14 at 23:34
• Thanks for your advices. I'm trying Tom Leek's solution and go on searching a lot. – Stéphane GROSSMANN Jul 26 '14 at 7:53

Since you generate the user-specific keys, you can also keep a copy of these keys somewhere (somewhere safe, preferably) and use them when needed.

Alternatively, you can generate the keys with a cryptographic derivation system which uses a "superkey" and the user's identity. For instance, consider the following:

• The superkey is K.
• A user is identified by his name/login/email u.
• The key for user u is computed as: Ku = HMACK(u)

I.e. you use HMAC, using K as key, to compute the user-specific key. Since HMAC is deterministic, you can always do the same computation again, as long as you know the "superkey".

Of course, the "superkey" is sensitive; it must never be known to anybody else than the superadmin. In particular, you MUST NOT "hide" the superkey within some application code that goes to the user's machine. This can be a problem if the user key generation is supposed to happen on the user's machine (that is, it is done by "you" in the sense that it is "your application", but still on the user's computer or smartphone, thus within range of reverse engineering).

This HMAC-based mechanism is, really, a kind of efficient compression method for the same initial model, i.e. you keep a copy of the users' keys. (If that sentence seems obscure to you, then you don't know enough (yet) to securely deal with cryptography.)

• The problem is that my application is offline. So, no way to do that outside my application. Every user stores his String encoded with his personal key on an external device (file in sd card) in order to read it later. And I need the superuser to be able to decode it too. – Stéphane GROSSMANN Jul 25 '14 at 14:11

The only way I can think of is to use asymmetric keys.

1. Generate an asymmetric key pair KS on the server. Retain the private key from this pair and hand out the public key to every single user.
2. Generate an asymmetric key pair KC for every single user. Let the user retain the private keys from their pairs and send the public keys to the server.
3. Every time server has to send something to a specific user, it encrypts it using its private key first and then with the user's public key. The user then decrypts the data first with their private key and then with the server's public key.
4. Every time a user has to send something to the server, they encrypt it using their private key first and then with the server's public key. The server then decrypts the data with its private key, followed by the user's public key.

You will need to make sure that users' public keys are well protected on the server. If there is a server breach and the keys (server's private key and users' public keys) leak out, anyone will be able to read anyone's data.

If you wish to change your server's key pair, you can generate a new key pair and distribute its public key to users. You will have to handle key versions (which data was encrypted with which key). Similarly, users can change their key pair and send updated public keys to the server.

• A public key should be public. If the server is the only one to know the public key, why not using a symmetric key ? Encrypt the message with the server private key is pointless, as everyone should know its public key. By the way, I don't think this answers the question. – Antoine Pinsard Jul 25 '14 at 11:40