What is the recommended way to generate a long unique cryptographic hash

2 points by hvasishth ↗ HN
I want to serve images that belong to users. For various reasons I want to serve the images unauthenticated. Even though the images would be served unauthenticated I don't want a rogue user to be able to guess the final URL for the images easily.

So I want to use something like what Google Docs does for images embedded in Google Docs. The images are available publicly, however, the url is hard to guess. For example here is a url to an image embedded in one of my docs.

https://lh5.googleusercontent.com/0gKizTE7velVl87okXLPS9Lwih_qS1koUzIhlVjXi4iG4S5HAAtF-U5QDR_Hq3UYNWFsT9DGA4GYA1sYG7iDoSCxvB5aGy0a2hYKUM5lusvj5fkbVAL1hNxODDDNJMLQg0C0fGQ

How do I generate a similar hard to guess url?

1 comment

[ 0.23 ms ] story [ 13.3 ms ] thread
Basically you use (a) a cryptographic hashing function or (b) encrypted Base64 data. The former makes shorter URLs while the latter gives you more to work with on the server side.

In DotNet, System.Security.Cryptography.SHA256Managed::ComputeHash() is a good start for making a hash. Then, of course Convert.ToBase64String() could be used to make the string, but be sure to replace the '+', '/', and '=' with different characters to make the string URL-friendly.

For a hash-based solution, there should be no need whatsoever to exceed 256 bits in cryptographic length, particularly since trying random URLs is a time-consuming activity. In fact, 64 bits may be sufficient in the real world. Even if someone could brute-force one hundred million combinations a second, it would still take on average ~389 million years to crack 64 bits. However, if the salt and algorithm are known to the attacker, it could become a dictionary attack, which is worlds easier. A good middle ground would be 128 bits, or 24 Base64 characters.

In the case of Google Docs, they are probably using PKI-encrypted binary data (such as perhaps an internal account ID) encoded in Base64, rather than merely a hash. This could make lookups and redirects more efficient (and less troublesome) to process, while making the URL less human-friendly.

Using SSL is recommended if at all possible -- to prevent playback attacks. Alternatively, playback attacks can be minimised by using a proper nonce and timeout. Furthermore, make sure you use a good random salt if using a hash and computing it from simple information such as the user's login username.