在Web应用程序中收集熵以创建(更多)安全随机数

H M*_*H M 12 php cryptography web-applications entropy prng

经过几天的研究和讨论,我想出了这种方法来收集访客的熵(你可以在这里看到我的研究历史)

当用户访问我运行此代码时:

$entropy=sha1(microtime().$pepper.$_SERVER['REMOTE_ADDR'].$_SERVER['REMOTE_PORT'].
$_SERVER['HTTP_USER_AGENT'].serialize($_POST).serialize($_GET).serialize($_COOKIE)); 
Run Code Online (Sandbox Code Playgroud)

注意:pepper是手工设置的每个站点/设置随机字符串.

然后我执行以下(我的)SQL查询:

$query="update `crypto` set `value`=sha1(concat(`value`, '$entropy')) where name='entropy'";
Run Code Online (Sandbox Code Playgroud)

这意味着我们将访客请求的熵与已经收集的其他人的熵相结合.

就这样.

那么当我们想要生成随机数时,我们将收集的熵与输出结合起来:

$query="select `value` from `crypto` where `name`='entropy'";
//...
extract(unpack('Nrandom', pack('H*', sha1(mt_rand(0, 0x7FFFFFFF).$entropy.microtime())))); 
Run Code Online (Sandbox Code Playgroud)

注意:最后一行是phpseclib的crypt_rand函数的修改版本的一部分.

请告诉我您对该方案的看法以及有关熵收集/随机数生成的其他想法/信息.

ps:我知道像/ dev/urandom这样的随机源.这个系统只是一个辅助系统或(当我们没有(访问)这些来源时)一个后备方案.

MrG*_*mez 11

在最好的情况下,您最大的危险是本地用户披露信息漏洞.在最糟糕的情况下,整个世界都可以预测您的数据.任何可以访问相同资源的用户:相同的日志文件,相同的网络设备,相同的边界网关,或者您和远程连接之间运行的同一行允许他们通过展开您的随机数来嗅探您的流量发电机.

他们会怎么做?为什么,基本应用信息论和一点知识 密码,当然!

不过,你没有错误的想法!使用真正的随机来源为您的PRNG播种通常对防止上述攻击发生非常有用.例如,如果系统具有低熵或其随机性源是可再现的,那么理解如何/dev/random在每个系统基础上填充的人可以利用这种相同级别的攻击.

如果您可以充分保护熵池的过程(例如,通过安全线路从多个来源收集数据),那么当您越来越接近理想时,某人能够收听的可能性会变得越来越小一次性密码的加密质量.

换句话说,不要在PHP中使用单个Mersenne twister中的单一随机源.通过阅读您最好的,系统特定的替代方案/dev/random,从尽可能多的安全,独特的"真实"随机源播种其熵池,做到这一点.我知道你已经声明这些随机性源是无法访问的,但是当所有主要操作系统都提供类似的功能时,这个概念很奇怪.所以,我想在这种背景下我发现"辅助系统"的概念是可疑的.

这仍然容易受到当地用户认识到你的熵源的攻击,但是保护机器并增加真正的熵/dev/random将使他们更难以完成他们的肮脏工作而不是一个人. - 中间攻击.

至于/dev/random确实可以访问的情况,您可以相当容易地播种:

  • 查看系统上存在哪些选项以供使用 /dev/hw_random
  • 拥抱rngd(或一个很好的替代方案)来定义随机性来源
  • 使用rng-tools检查和改善你的随机性的个人资料
  • 最后,如果您需要良好,强大的随机性来源,请考虑投资更专业的硬件.

祝您申请安全.


PS:您可能希望将来在Security.SECryptography.SE上提出这样的问题!