I’d like to uniquely identify users by issuing security tokens to them. In order to guarantee non-repudiation I’d like to ensure that no one has access to the user’s private key, not even the person who issues the tokens.
What’s the cheapest/most-secure way to implement this?
Use a 3rd party certificate authority: you don’t know the private key and you don’t have to care about how the client gets and secures the private key (but you can worry about it). Not the cheapest solution ever…
OR:
Share a secret with each client (printed on paper, through email, phone, whatever…).
Have the client generate the keys based on that secret, time (lets say 5 minute intervals) and whatever else you can get (computer hardware id – if you already know it, client IP, etc…). Make sure that you have the user input the secret and never store it in an app/browser.
Invalidate/expire the tokens often and negotiate new ones
This is only somewhat safe (just like any other solution)…if you want to be safe, make sure that the client computer is not compromised.
It depends on where/how you want to use those keys* but the bottom line is that in the case of asymmetric keys, the client will encrypt the data sent to you (the server) using their private key and you (the server) will decrypt that data using the client’s public key (opposite of how HTTPS works).
Can you verify, at any point in time, the identity of your clients?
If the client computer is compromised, you can safely assume that the private key is compromised too. What’s wrong with SSL/HTTPS. Do you really need to have one certificate per client?
Tokens are not the same thing as keys and they don’t have to rely on public/private keys. Transport, however, might require encryption.
*my bank gave me a certificate (which only works in IE) used to access my online banking account. I had to go through several convoluted steps to generate and install that certificate and it only works on one computer – do you think that your clients/users would agree to go through this kind of setup?