随机字符串与哈希(随机字符串)?

信息安全 哈希 随机的
2021-08-11 22:59:25

我正在实施一次性令牌服务。这些一次性令牌中的每一个都代表一些与之关联的服务器端数据/操作(例如“电子邮件确认”操作),以便我的 Web 服务可以在没有会话的情况下验证并采取行动。(来自电子邮件的确认链接;来自二维码扫描;...)

这些令牌应该很难猜测或伪造。所以我认为一个长的随机字符串(来自/dev/urandom)应该足够好了。但来自https://en.wikipedia.org/wiki//dev/random

/dev/random 的对应物是 /dev/urandom(“无限”[5]/非阻塞随机源[4]),它重用内部池以产生更多伪随机位。这意味着调用不会阻塞,但输出包含的熵可能比从 /dev/random 中相应读取的少。虽然 /dev/urandom 仍被用作适用于大多数加密目的的伪随机数生成器,但有些人声称 /dev/urandom 不推荐[谁?] 用于生成长期加密密钥。然而,通常情况并非如此,因为一旦熵池是不可预测的,它就不会通过减少位数来泄漏安全性。

而且我还在 werkzeug 的会话中阅读了一些代码https://github.com/mitsuhiko/werkzeug/blob/master/werkzeug/contrib/sessions.py

def _urandom():
    if hasattr(os, 'urandom'):
        return os.urandom(30)
    return text_type(random()).encode('ascii')

def generate_key(salt=None):
    if salt is None:
        salt = repr(salt).encode('ascii')
    return sha1(b''.join([
        salt,
        str(time()).encode('ascii'),
        _urandom()
    ])).hexdigest()

所以我的问题是:这样会hash(time()+urandom())产生比 pure 更多的“随机”字符串urandom()吗?在这里使用哈希函数的目的是什么?

1个回答

真正的随机数据是 100% 不可预测的。像 urandom 这样的接口在此之上还提供了均匀分布,也就是说,您不仅会得到不可预测的随机值,而且所有值都具有相同的概率。如果您已经拥有如此高质量的随机源,那么散列将不会再改善它,即hash(time()+urandom())不会比urandom()单独使用更好。

但是如果您的代码示例回退到简单random()函数urandom()不可用。这通常只是一个快速的伪随机数生成器,如果您对先前的值足够了解,那么这些值是可以预测的。因此,当仅面对伪随机数生成器时,将输出与盐和时间一起散列可能是试图使输出难以预测。虽然它并没有真正为输出增加更多随机性,但它使恢复原始伪随机值变得更加困难,从而使得对底层伪随机数生成器的攻击变得更加困难。对于真正的随机数据,您不需要这种保护,因为输入数据已经完全不可预测,如果已知前一个随机值,则无法计算下一个随机值。