crypto/rand如何生成安全随机数?

How does crypto/rand generate a secure random number?

我开始极客了,我想看看 https://golang.org/src/crypto/rand/rand_unix.go 内部是如何工作的。

我想看看它什么时候从 dev/random 生成随机数(更安全)以及什么时候从 dev/urandom(安全性较低)

生成

看起来如果 rand_batched.go 已初始化(这会初始化 altGetRandom)并且 GOOS 不是 plan9(那么 r.name = urandomDevice 它将 return 随机数组的长度而不是内容(这很奇怪,为什么这么长?)

见第 57 行:

if altGetRandom != nil && r.name == urandomDevice && altGetRandom(b) {
        return len(b), nil
    }

否则它只会 return 仅当 GOOS=plan9.

时才会基于 dev/random 的数组内容

那么为什么要 return len(b)? 在我看来,大多数时候它会使用 dev/urandom 这是次优的......我错了吗(因为文档所以猜测,但帮助我理解)?

altGetRandom用于有系统调用获取随机字节的系统,而不是依赖于/dev/urandom的存在。这 有时 在特殊环境中很有用(没有 /dev、Docker-ish 系统且 weird/wrong /dev、 FreeBSD jails with a incorrect /dev setup, etc.),并且比打开文件快一点(因为它没有经过那么多的系统调用层),但通常应该只使用该文件.

有问题的调用是在一个 io.Reader 风格的函数中,其工作是 return 读取的字节块的长度,以及任何错误。使用系统调用时,OS 完整地填充(或假定填充)数组 b,因此 len(b) 是正确的结果。