Re: How to create an UUID (Version 1)
- Posted by ghaberek (admin) Sep 30, 2018
- 3860 views
So I've been doing a lot of reading about UUIDs.
- UUIDs generally do not meet security requirements
- Is it safe to rely on UUIDs for privacy?
- Is UUID.randomUUID() suitable for use as a one-time password?
- UUID or GUID as Primary Keys? Be Careful!
- AppSec Concerns: UUID Generation
- How secure are GUIDs? Can I use it to generate passwords?
- What is an UUID / GUID
- Why Auto Increment Is A Terrible Idea
- A brief history of the UUID
- MySQL 8.0 Reference Manual :: UUID()
- Auto-Incrementing IDs: Giving your Data Away
- Guide to Cryptography / Safe UUID generation
- Commons Id - UUID Documentation
- The Quick Guide to GUIDs
- Choose UUIDs for model IDs in Rails
- Looking at Ramsey UUID
- Primary Keys: IDs versus GUIDs
Obviously there are a lot of opinions on the topic. I think the best synopsis this comes from this article: AppSec Concerns: UUID Generation.
- Generate UUIDs on the server, if possible. This will ensure a sufficiently strong algorithm can be used to generate the UUID.
- Use a strong UUID algorithm. Choosing a cryptographically secure PRNG will reduce the chance of a collision. Most major development platforms have secure UUID libraries (e.g., Java’s uuid.randomUUID() method).
- Plan for collisions. Ensure that applications and servers behave safely and consistently if they encounter identical UUIDs for different records or objects.
- Don’t rely on UUIDs for security. Never use UUIDs for things like session identifiers. The standard itself warns implementors to “not assume that UUIDs are hard to guess; they should not be used as security capabilities (identifiers whose mere possession grants access, for example).”
I'll add to that:
- UUIDs which include a MAC address provide sensitive information about your system. By using uuid_generate/UuidCreate or random numbers, this will not be included.
- UUIDs which are time-based will always be chronological. Again, this is sensitive information about the system, which could be used by an attacker, and should be avoided.
Based on all that, here's my suggested implementation:
public enum type uuid_source_t -- attempt SYSTEM, then RANDOM, then LEGACY UUID_SOURCE_DEFAULT = 0, -- use the system library to generate a UUID. -- return {} if no system library exists UUID_SOURCE_SYSTEM, -- use the system CSPRNG to generate a UUID. -- return {} if no CSPRNG source exists UUID_SOURCE_RANDOM, -- generate a timestamp + random MAC address UUID. -- always returns a value UUID_SOURCE_LEGACY end type -- -- Returns TRUE if we have a system library for generating UUIDs. -- public function uuid_have_system_source() -- -- Returns TRUE if we have a system-wide CSPRNG source for UUIDs. -- public function uuid_have_random_source() -- -- Returns which method to be used by UUID_SOURCE_DEFAULT. -- public function uuid_default_source() -- -- Generate a new UUID. -- public function uuid_generate( uuid_source_t source = UUID_SOURCE_DEFAULT ) -- -- Convert a UUID to its string representation. -- public function uuid_format( uuid_t uuid ) -- -- Parse a string into a UUID. -- public function uuid_parse( string str )
-Greg