1

I need to create unique and long tokens for email verification, but I am not sure about how. Currently we are on staging servers or we are just using os.urandom() in Django. But I need to know what the right way to go about the same is. Is guid() secure enough for the same? Basically these are login tokens that need to be stored for a long time and need be unique.

Also on the same topic, in order to make stuff a little more efficient for us, can we use XOR enc to store data in the string itself to optimize the DB queries?

Anders
  • 64,406
  • 24
  • 178
  • 215
georoot
  • 113
  • 1
  • 5

3 Answers3

6

Using os.urandom() is perfectly alright. It generates a cryptographically secure random stream of bytes. This would be impossible to guess for anyone.

Using guid() is also pretty secure, although not totally random.

Using XOR to encode parameters into your token is a bad idea. For one, it is vulnerable to bit flipping attacks. Even if the user can not decode the token, he may alter the contents encoded in it. A better solution is to send a HMAC along with the data, so that the user can not tamper with it.

Sjoerd
  • 28,707
  • 12
  • 74
  • 102
  • just a clarification, with large number of tokens generated, is there a chance of collision in os.random() – georoot May 03 '16 at 09:52
  • 1
    No, the chance of collision is negligible if you use enough random bytes (i.e. 16 or more). [This article](https://en.wikipedia.org/wiki/Birthday_attack) has some numbers on the chance. With 16 bytes, creating 10^18 tokens has a 1% chance of collision. So you can safely create a million million million tokens before running into problems. – Sjoerd May 03 '16 at 09:59
  • 1
    I'm not sure how you define "pretty secure". I would say it is insecure, unless generated by a CSPRNG. The cost of using an CSPRNG instead is so minimal, it doesn't make sense to be lazy and use GUIDs instead which are at the whim of their implementation of generation, which could change at any point of library upgrade or change. – SilverlightFox May 04 '16 at 09:44
  • @SilverlightFox, you are right. The security of GUIDs depends mainly on the implementation. Since the only secure implementations are the ones that call a secure random number generator, you can just as well call the secure random number generator yourself. – Sjoerd May 04 '16 at 10:26
2

Using os.urandom() uses accepted cryptographically secure sources, so continue to use that if you can, otherwise there should be another way to access the same, or similarly secure random sources in the implementation you are using (php java). The most important thing is that it cannot be predictable, which means any sort of seeding done manually (for example using the time) is a bad idea.

Edit: Can you clarify what exactly you mean by 'use XOR enc to store data in the string'?

Edit 2: I'd like to point out that using even a random GUID is not a good way of doing this (except maybe in Java). Most methods of creating a GUID are relatively deterministic, and while they may be good for avoiding collisions, the other characteristic that you want from a password reset token is unpredictability.

C_Sto
  • 311
  • 1
  • 5
1

can we use XOR enc to store data in the string itself to optimize the DB queries?

Yes, but it will no longer be called a token, but rather a ticket (if using a symmetric encryption) or certificate (if using symmetric encryption). Like tokens, tickets and certificates are string used for authentication, but they actually contain encrypted and/or cryptographically signed data, rather than just a random number.

The server issues a ticket/certificate, encrypting any authentication details like who the user is, and their permissions, a timestamp and validity period, and possibly a salt. To authenticate, the server decrypts the ticket/certificate and validates these values. Tickets and certificates are often used in distributed authentication without a central server or where the central server may be unreachable from the application.

Tickets and certificates are more difficult to implement securely, compared to tokens; but due to their decentralized nature, they can scale better and be usable in situations where central authentication isn't possible.

I would, however, recommend something more specific than XOR encryption. While XOR is a part of many stream cipher, the hard part in doing XOR encryption is generating the pseudo random stream that you used to XOR to the data.

Lie Ryan
  • 31,089
  • 6
  • 68
  • 93