math/rand ist ein deterministischer PRNG mit globaler Seed-Quelle; aus wenigen Ausgaben kann ein Angreifer den Seed rekonstruieren und alle künftigen Tokens vorhersagen. crypto/rand zieht aus dem CSPRNG des Betriebssystems — getrandom unter Linux, RtlGenRandom unter Windows, /dev/urandom unter macOS — und meldet Lesefehler, statt heimlich auf einen schwachen Fallback umzuschalten. Die Bytes mit base64.RawURLEncoding zu kodieren liefert eine kompakte, URL-sichere Zeichenkette ohne Padding. Das 16-Byte-Minimum schützt gegen Birthday-Kollisionen bei realistischen Session-Mengen; 32 Bytes sind in Produktion üblich.
package mainimport ("crypto/rand""encoding/base64""fmt")func newToken(nBytes int) (string, error) {if nBytes < 16 {return "", fmt.Errorf("need >=16 bytes, got %d", nBytes)}b := make([]byte, nBytes)if _, err := rand.Read(b); err != nil {return "", fmt.Errorf("crypto/rand: %w", err)}return base64.RawURLEncoding.EncodeToString(b), nil}func main() {tok, err := newToken(32)if err != nil {panic(err)}fmt.Println(tok)}