最近用到 secure random 来生成 session token,稍微调研了一下这个 lib 的负面新闻,然后找到了:
https://bugs.ruby-lang.org/issues/9569
大意是 secure random 使用 openssl 生成随机数不够好,敦促 core team 换用/dev/urandom 实现。其中一个重要的理由是:openssl random number generator 不是 fork safe 的,也就是在 unicorn 这类 fork 之后的进程里会产生重复随机数。
而帖子中有人提到这个 issue 已经被 ruby 处理过了,我查找到了 https://bugs.ruby-lang.org/issues/4579 ,原来 SecureRandom 在生成随机数之前会检查一下 pid,如果和之前存下的不吻合,就意味着 fork 了新进程,要把新的 pid 作为熵引入到 openssl 里。
真可靠啊...
相比之下,PHP 就没这么幸运了: https://github.com/ramsey/uuid/issues/80
这哥们在生产环境生成 1M 组 uuidv4,就遇到了几百组重复.....而且这是去年八月的 issue,今年二月查明.....
实际中我用了个 256bit 的随机 hex 做 token,比 uuidv4 的 122bit 大不少,但是感觉用随机数还是有出问题的可能,应该考虑换用 uuid v1。
v1 的话虽然有个 uuid gem,但也不知道可不可靠,毕竟还挂着个 collision 的 issue...