views:

72

answers:

4

I need to develop a feature in the system which allows unregistered users to get one-off system access via URL token that is generated/sent by an authenticated user.

For example, a user logs in and wants to share a piece of information so the system generates a URL like http://host/page?token=jkb345k4b5234k54kh5345kb34kb34. Then this URL is sent to an unregistered user who would follow the URL to get some limited access to normally protected data.

First question - are there any standards (RFC? IETF? others?) that would be defining URL generation? The only ones I was able to find are RFC2289 and OpenToken, but none of these are directly related to what I need to do and the latter is only in a second draft state.

There is another design consideration: whether to use one way crypto hash functions and store the payload in a local data store VS using private-public key pairs and encode all necessary payload in the unique string itself.

At the moment I am heavily leaning towards one way hash as it would give me much more freedom (no dependency between payload size and generated string) and less potential problems in the future (e.g. what if I decide to add more payload - how to ensure backwards compatibility). Last but not least, accidental exposure of server-side private key would require massive efforts in key regeneration, update of all live instances, etc. None of these problems are relevant if choosing one-way hash option, but maybe there's something I overlook? RFC2289 prefers one way crypto function whereas OpenToken chooses the key pair option.

And finally, is anybody aware of any Java library for generating these?

Thanks in advance.

+1  A: 

Also have a look at http://en.wikipedia.org/wiki/Universally_unique_identifier and RFC4122. Inside the backend you would need to attach the generated uuid to your entity so verification based on the UUID can be done later.

Apart from that most often the token could include some data (e.g. versioning+userdata) and then a secure MD5-hash is used to 'obfuscate/anonymize' it. Later then the data is concatenated by server and the hash-values are compared again.

Regarding java-lib and uuid have a look at UUID-javadoc.

manuel aldana
+1 for mentioning RFC4122 and UUID Wiki link.
mindas
UUIDs are unique, but they don't provide any guarantees on predicability. Knowing a bit about the machine generating the UUID, you could likely narrow down the search space quite substantially.
Nick Johnson
A: 

You only need a token when a user shares one piece of information. So, can't you just generate a random token, and associate this with the piece of information (e.g. a database field)? It's a lot simpler than doing any crypto stuff...

ivy
I can do either way, but more wanted to know if there is any standard for similar situations. To rephrase - to code is easy, but I want to do a decent analysis phase first.
mindas
+1  A: 

Generate random strings and store them in a database with credentials.

The codes generated need to have two properties: complexity and uniqueness. Complexity ensures that they cannot be guessed and uniqueness ensures that the same code can never be generated twice. Beyond this, the specific method doesn't matter.

Generate token strings with two parts to them. The first part is time-dependent, where the key will increment and change in a predictable way with each millisecond. The second part is completely random. Combined, this will give you a long string that is unique and complex.

When you generate the token, store it in the database with the credentials that are granted when this token is used. It's important that these credentials are not encoded into the string, since this ensures that the strings cannot be hacked.

When the user click on the link with the token, mark that token as used in the database. Even better is to set a timestamp for the use, so that it can be expired, perhaps, 24 hours after the first click. This approach gives you the flexibility to implement this specific part of the requirement as necessary for your project.

I've used this solution before in many different cases for not only one-off system access, but also for ticket admission codes, gift certificate codes, and anything that's one-time use. It doesn't matter so much what you use to generate the token, so much as you can guarantee its complexity and uniqueness.

Erick Robertson
+1  A: 

Here's how I would have done it:

  1. Create a token (you could use a UUID for this) and add it to your database along with creation time and what resource the token should grant access to
  2. Send an email to the user with the url http://www.myserver.com/page?token=
  3. When the user navigates to the url, create a new session with the desired timeout and mark that session as authorized to view whatever the database says the user should be able to see (If the token isn't too old. Check the creation time against current time)
  4. Either delete the token from the database, or mark it as expired
kskjon