Is it a good idea to generate a secure random hex string until the process succeeds?
All examples I've come across show that if rand.Read
returns error, we should panic, os.Exit(1) or return empty string and the error.
I need my program to continue to function in case of such errors and wait until a random string is generated. Is it a good idea to loop until the string is generated, any pitfalls with that?
import "crypto/rand"
func RandomHex() string {
var buf [16]byte
for {
_, err := rand.Read(buf[:])
if err == nil {
break
}
}
return hex.EncodeToString(buf[:])
}
Is it a good idea to loop until the string is generated,
That depends. Probably yes.
any pitfalls with that?
You discard the random bytes read on error. And this in a tight loop. This may drain you entropy source (depending on the OS) faster than it can be filled.
Instead of an unbound infinite loop: Break after n rounds and give up. Graceful degradation or stopping is best: If your program is stuck in an endless loop it is also not "continue"ing.
No. It may always return an error in certain contexts.
Example: playground: don't use /dev/urandom in crypto/rand
Imagine that a machine does not have the source that crypto/rand gets data from or the program runs in a context that doesn't have access to that source. In that case you might consider having the program return that error in a meaningful way rather than spin.
More explicitly, if you are serious in your use of crypto/rand
then consider writing RandomHex
such that it is exceptionally clear to the caller that it is meant for security contexts (possibly rename it) and return the error from RandomHex
. The calling function needs to handle that error and let the user know that something is very wrong. For example in a rest api, I'd expect that error to surface to the request handler, fail & return a 500 at that point, and log a high severity error.