1

So far I see these options (pseudo code):

A. Quite simple MD5 hash:

$identifier = MD5(object.id + created_at + app_secret)

=> 4c0dc8d3fdffacb65d04911291aac4cf

B. UUID:

$identifier = uuid()

=> fbcf6520-ab93-11e8-86b4-080027b55b5e

But which UUID version makes most sense? I tend to v4.

C. I'd like to have a prefix for those IDs, so I immediately know what kind of object is meant e.g. in the logs or support request.

$identifier = 'trx_' + uuid()

=> trx_fbcf6520-ab93-11e8-86b4-080027b55b5e

But is this a nice style? I could store without prefix but expose with prefix and allow requests with or without it.

What's your best praktise?

Evert
  • 93,428
  • 18
  • 118
  • 189
ownking
  • 1,956
  • 1
  • 24
  • 34
  • I'm not quite sure what you are trying to solve here. A REST client usually shouldn't care about your resource identifier as it will only invoke URIs received as response of a request issued to some of the API endpoints. URIs are by definition unique. A resource identifier that supports this feature is for sure safe to use therefore. How you generate such identifiers is totally up to you and more or less an implementation decision. No benefits here to gain IMO – Roman Vottner Aug 29 '18 at 15:21
  • First I want to avoid double IDs without need of checking the exisiting IDs bevore every new insert. And second it would be nice to have an indicatior for what kind of object the ID is for (less important). – ownking Sep 04 '18 at 10:59

1 Answers1

1

It shouldn't really matter. If I used UUID-like identifiers, I do think I would slightly prefer the UUID format because it signals to a user of an API 'This is a UUID'.

It's possible that there's some small benefits for a user, because if I see a UUID, I know I can store it in a database as a 128 bit integer instead of a string.

One thing to look out for though is security. Your first example uses the word secret which might tell me that these id's should not be guessable. UUID's are guessable and not cryptographically secure.

That being said, MD5 is insecure too so in that case both your examples are bad.

Evert
  • 93,428
  • 18
  • 118
  • 189
  • Thanks for you answer. Mainly it should be avoided to expose the DB IDs and that someone can just go through all objects too easy by increasing the ID. But there is no need for an uncrackable algo. Do you have a better suggestion or would you say for a standard API ID UUID should sufficient? – ownking Sep 04 '18 at 10:56
  • 1
    @ownking, UUID is simply *not good* for this. They're very predictable. Even if you don't need super high security, it's a good idea to just use security best practices. Check out the openssl_random_pseudo_bytes() function. – Evert Sep 04 '18 at 11:00
  • @ownking While [UUIDs are not completly randomized in Java](https://stackoverflow.com/questions/7532807/are-java-random-uuids-predictable) I guess 122 out of 128 bits of randomness is more than enough for any API IMO. – Roman Vottner Sep 04 '18 at 11:56
  • @RomanVottner one problem is that UUID's are not guaranteed to be cryptographically secure. The fact that a specific UUID implementation written in Java does do this, is an implementation detail. The UUID implementation in Java might even be different per JVM. There's no guarantee here. – Evert Sep 04 '18 at 12:27
  • Of course, if you write your own implementation for generating type 4 UUID's and you use a cryptographically random source, there's nothing wrong with using UUID's. – Evert Sep 04 '18 at 12:29
  • 1
    I agree that if you implement a UUID algorithm that simply counts upwards you will be vulnerable to guessing-attacks and such, though I wouldn't sign a statement that UUIDs are predictable in general. If you use such implementations you basically call for trouble. Which kind of identifiers are used are an implementation detail not of big relevance to clients, IMO. And for most APIs out there the default UUID implementation that ship with their framework should be enough. For security-critical stuff one might instead switch to other algorithms – Roman Vottner Sep 04 '18 at 12:38
  • I've seen several implementations of UUID's that were trivial to predict, so as a general rule I would say, don't rely on UUID's to be secure unless your specific implementation guarantees it. – Evert Sep 04 '18 at 13:08
  • And if one of the requirements of your API is to not have guessable urls, this is enough reason to not just 'pick whatever default UUID implementation is close by' and spend a few seconds on making sure it's good enough. – Evert Sep 04 '18 at 13:11
  • @Evert: At the end it's more important that the change of having two identical IDs is very very low than having easy predictable IDs. And I guess thats the case with UUID and that's what it's made for, right? You are right, for IDs which are e.g. used for a secret document link, something like openssl_random_pseudo_bytes is the better choice, would UUID5 also be an option if random name parameter is used? – ownking Sep 05 '18 at 11:36
  • 1
    Hi @ownking. Yes UUID is meant for uniqueness not, making them hard to guess. Some implementations might make them hard to guess too. It's not hard to make your own UUID v4 string with openssl_random_pseudo_bytes. Should be faster than me writing the answer here and all these comments ;). You don't want v5, you want v4. – Evert Sep 05 '18 at 11:42