Hi. How can I generate a unique sessionID? I want ...
# server
t
Hi. How can I generate a unique sessionID? I want users to login via username and password and then generate a sessionID that is saved in database and in a cookie.
y
UUID.randomUUID()
?
👍 1
m
If you just need a unique identifier,
UUID.randomUUID()
is good about giving unique values. However, it gives easy-to-guess values, which makes it less than ideal for something like a session-cookie, because I could look at my session-cookie, and then write a simple test that guesses other "nearby" values and tries them until i can find some other poor unsuspecting user's session-cookie. Something like the following will give hard-to-guess values, but lack a uniqueness guarantee.
Copy code
val secureRandom = java.security.SecureRandom()
...
secureRandom.nextInt()
I think you could combine both approaches to get something that would give you a value that is both unique and hard to guess:
Copy code
// during app startup
val secureRandom = java.security.SecureRandom()
...
//when creating an app session
val sessionIdentifier = UUID.randomUUID() + secureRandom.nextInt()
However, much has been written about all the ways that we can get session-management wrong, so my answer is probably pretty flawed too. If you're using Ktor, you might consider using their session management (I haven't used it, but I'd guess that it's implemented more carefully than my nonsense above): https://ktor.io/docs/sessions.html If you need to roll your own session management, be sure to review the OWASP guide to avoiding common pitfalls: https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html
r
owever, it gives easy-to-guess values
Is that not version specific and also hard to attack (like you need a few to start to find it which hopefully other security aspects protects you from). you could also use a salted hash over the UUID with the salt per user to help a lot. the risk of collisions should be acceptable for most
m
Yes, you are right! I didn't realize that
randomUUID()
is a type-4 UUID (although in hindsight it probably should've been obvious). The javadocs say the following about
randomUUID()
:
The 
UUID
 is generated using a cryptographically strong pseudo random number generator.
I think the biggest flaw with it, then, is just that it's only 122 bits of randomness, which is still kind of easy to search a large space of that. https://neilmadden.blog/2018/08/30/moving-away-from-uuids/ The above article recommends using something like the following (translated into Kotlin):
Copy code
class SessionIdGenerator {
  val random = java.security.SecureRandom()
  val encoder = java.util.Base64.getUrlEncoder().withoutPadding()

  fun newId() : String {
    val data = ByteArray(20) // 20 bytes = 160 bits of randomness
    random.nextBytes(data)
    return encoder.encodeToString(data)
  }
}
❤️ 1
r
I
t
I thank you for your answers. I will read through the "Moving away from UUIDs" article. I have already read quite a lot. I didn't find the ktor docs for sessions helpful. They are about general Session handling, but I didn't find anything about session IDs (let alone generating them). It's such a critical topic, that I like to know what's going on under the hood. From what I've read, there's so much you can do wrong.
342 Views