-
Notifications
You must be signed in to change notification settings - Fork 18.9k
Description
Update, Jun 27 2024: The current proposal is #67057 (comment)
Random strings are useful as passwords, bearer tokens, and 2FA codes.
Generating them without bias from crypto/rand is not trivial at all, and applications are lured into using math/rand for it. See greenpau/caddy-security#265 for example.
I propose we add a top-level function that takes a charset and returns a string of elements randomly selected from it.
The length of the string is selected automatically to provide 128 bits of security. If uppercase and lowercase letters and digits are used, a string will be ceil(log62(2^128)) = 22 characters long.
If more than 2^48 strings are generated, the chance of collision becomes higher than 2^32, but that's also true of UUID v4. Callers that reach those scales could call String twice and concatenate the results, but it doesn't feel worth documenting.
There is no error return value on the assumption that #66821 is accepted. That allows convenient slicing if necessary.
// String returns a random sequence of characters from the supplied alphabet.
//
// The length of the returned string is selected to provide 128 bits of entropy,
// enough to make a brute-force attack infeasible. If a shorter string is
// needed, for example as a one-time token, the caller may truncate the result.
//
// The alphabet is interpreted as a sequence of runes, and must contain at least
// two Unicode characters, or String will panic.
func String(alphabet string) string
This can't really be implemented in constant time, but since it always runs randomly, attackers can get only a single timing sample, which limits the maximum theoretical leak to a few bits.
Do we already have constants for the most common charsets defined somewhere?
/cc @golang/security @golang/proposal-review