Reputation: 637
I'm creating an app where in, a client sends a request to the server and in turn gets a unique request id. This unique request id would be used later authenticate the client when it wants to interact again with the server.
The request of client are of two types:
My problem is how do I generate the id? I'm using Java and MySQL server database. If I use an auto-incremented database generated id, then it becomes too easy for the client to guess the ids. Another client could maliciously generate a few ids by guessing and misuse them (There is no authentication between the client/sever, except for the ids :< )
If I generate a random id using UUID or some other randomize algorithm, then I need to check the entire database (which could have thousands of records), to really check and guarantee if the random id is unique indeed? Or would it be fast inside the database to check if the id exits and won't cause performance issues?
What measures should I take? Do I need to have more security measures for authentication between the client and the server, other than the unique id?
Upvotes: 2
Views: 8673
Reputation: 21
If you use Spring Framework you may found useful another UUID implementation org.springframework.util.AlternativeJdkIdGenerator
:
IdGenerator generator = new AlternativeJdkIdGenerator();
UUID uuid = generator.generateId();
Which is from the documentation:
An {@link IdGenerator} that uses {@link SecureRandom} for the initial seed and * {@link Random} thereafter, instead of calling {@link UUID#randomUUID()} every * time as {@link org.springframework.util.JdkIdGenerator JdkIdGenerator} does. * This provides a better balance between securely random ids and performance.
Upvotes: 2
Reputation: 10994
Upvotes: 0
Reputation: 21122
Create an encoded and unique key for each session, that will be created using the unique data you have of that user, something like his email, current time, etc.
String yourString = "[email protected]"+"timestamp";
byte[] bytesOfMessage = yourString.getBytes("UTF-8");
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] thedigest = md.digest(bytesOfMessage);
Would generate a unique id for each request, store them in a table in your database that contains an expiry timestamp, userid and the key. The on each request, renew the "expiry" time if its still valid, or return error if its expired or invalid.
The valid keys table I use is something like:
userId(int)
key(varchar(32))
expiry(int)
Then if you wanted to see if a user has a valid session open you'd just check that table for the userId
and make sure that it's a unique column, to avoid storing a historic of previous sessions.
Upvotes: 2
Reputation: 493
If you 'd like to generate it on MySQL side, I think this will do just fine
md5(concat(UNIX_TIMESTAMP(),<user_id>))
If the field is indexed, query won't take long.
Upvotes: 1
Reputation: 34323
Using java.util.UUID.randomUUID();
you can generate a cryptographically secure, random UUID.
Since the UUID is 128 bit long, the chance for a collision is negligible, but if you really want to check for collisions, you can do that by storing active UUIDs in the database and check for duplicates after generation.
Upvotes: 2
Reputation: 16072
You can use Java's UUID. Something like :
UUID uniqueKey = UUID.randomUUID();
And if you don't wanna use that, you can use the time, as it is always changing, add a random number if u wanna be sure.
Upvotes: 2