HMAC for round-trip validation I have a need to produce URLs to allow the downloading of a single file, without authentication.  These links will be sent through email, and I understand and accept the risk of a given link being shared by its recipient (or intercepted in transit).

Each file is identified by a UUID, generated in SQL Server using NEWID().  I need to prevent an attacker who knows the link format from brute-force guessing other UUIDs and accessing other files shared this way. Note also that the links have an automatic expiration.

My current link scheme sends the UUID along with an HMAC.  The HMAC is generated using:


a payload composed of system-level salt + a per-file nonce salt + the UUID
a 128-byte system-level key to compute a SHA2-512 HMAC


Is any part of this superfluous or excessive? Does using HMAC gain me any additional security over a simple strong hash in this scenario?

For discussion about T-SQL NEWID(), see SQL Server : does NEWID() always gives a unique ID? on StackOverflow.
If you look at RFC 4122 then you can see which bits are not random. I think that are 128 bits in the UUID and 6 of them are non-random to indicate the scheme used. That leaves 122 bits of UUID, which is probably enough to consider them relatively random. Only if you generate many millions of them is there a chance of collision. However, there is a reason why a hash commonly has an output size of double the wanted security level because of the birthday paradox. And 122 / 2 = 61 bits of security, which is on the low side. So it might be a good idea to extend at least the randomness of the value.

Of course you can always add random bits to them and a MAC using a secret key would that. It would allow you to reject tries with relative confidence. Furthermore, you could reject those before a database lookup. How much confidence depends on the security of the MAC, usually limited by the output size of the MAC. It does of course require the additional burden of key management though.

Alternatively you could simply add more random bits to the UUID or to generate a proprietary 256 bit UUID. However, I think the MAC scheme over the UUID is relatively elegant as the MAC can be over the UUID, while keeping the UUID scheme intact, and it can be extended by adding a salt. Of course the secret key must be kept secret otherwise an adversary can generate the same.

The disadvantage is that the UUID as send with MAC and possible salt is not standardized anymore, so you have to think about an alternative canonical encoding of UUID and MAC.