I have nothing to show on the location app I’ve been building, but I’ve hit a hurdle that I felt warrants some discussion. I want to use two random strings that are unrelated to each other in order to make the app more secure. An ID for each location shared, and a key to prevent someone simply trying to enumerate all the ID’s. Because the key is a security device it is important that it is not derived from the ID, or from the same deterministic source as the ID. With this in mind I have been reading about the random number generator available in Go.

It shouldn’t come as a huge surprise that it is a deterministic pseudo random number generator, and you are required to provide a variable seed to get different results. Computers are pretty bad at randomness generally. Now most of the advice I have found suggests using the current time (to nano second precision) as the seed, and most of that advice comes with the caveat that it works but isn’t suitable for cryptographic functions. So I have faith that the people giving the advice are giving advice that is good for most use cases a Go novice is likely to need, unless that use case is more nuanced, or related to security. Unfortunately for me, as a complete novice to Go, my use case is somewhat more nuanced, and is related to security.

My issue is that I need two sets of random numbers (to generate random strings) that need to be unrelated. The current time could be suitable for the ID, it being predictable isn’t the end of the world, but the key needs to be more secure, and needs to be generated at close enough to the same time as the ID to make using the current time for both of them unworkable. Now I intend to host this app on Linux, and Linux keeps a good source of what we can consider essentially random data that can be read from /dev/random on most distributions. But reads from /dev/random block when the pool of randomness is empty and on a server the sources of random data that can fill that pool can be limited. Now there is a solution, /dev/urandom takes some of the randomness from the pool as a seed to a pseudo random number generator, that keeps generating random looking numbers for as long as you need. So while the random pool has data /dev/urandom is also pretty good as a randomness source, but when it’s empty it’s less good. So I have a choice, do I make my app slow when there isn’t enough random data, or do I allow it to be less secure? I’m probably going to go with less secure, as the data isn’t designed to be long lived enough to allow unlimited time to attack it, and because the data is only useful with context that should be external to the app (I hope). But this is a trade off that needs to be thought about whenever you rely on randomness in computer programs.

posted at 11:17 am on 1 Sep 2019 by Craig Stewart

Tags:project sysadmin golang location-finder