关闭 x
IT技术网
    技 采 号
    ITJS.cn - 技术改变世界
    • 实用工具
    • 菜鸟教程
    IT采购网 中国存储网 科技号 CIO智库

    IT技术网

    IT采购网
    • 首页
    • 行业资讯
    • 系统运维
      • 操作系统
        • Windows
        • Linux
        • Mac OS
      • 数据库
        • MySQL
        • Oracle
        • SQL Server
      • 网站建设
    • 人工智能
    • 半导体芯片
    • 笔记本电脑
    • 智能手机
    • 智能汽车
    • 编程语言
    IT技术网 - ITJS.CN
    首页 » PHP »PHP中的随机性——你觉得自己幸运吗?

    PHP中的随机性——你觉得自己幸运吗?

    2016-01-21 00:00:00 出处:ITJS
    分享

    本文分析了生成用于加密的随机数的相关问题。 PHP 5没有提供一种简单的机制来生成密码学上强壮的随机数,但是PHP 7通过引入几个CSPRNG函数来解决了这个问题。

    Cryptography Randomness in PHP

    什么是CSPRNG

    引用维基百科,一个密码学上安全的伪随机数发生器(Cryptographically Secure Pseudorandom Number Generator 缩写CSPRNG)是一个伪随机数生成器(PRNG),其生成的伪随机数适用于密码学算法。

    CSPRNG可能主要用于:

    密钥生成(例如,生成复杂的密钥) 为新用户产生随机的密码 加密系统

    获得高级别安全性的一个关键方面就是高品质的随机性

    PHP7 中的CSPRNG

    PHP 7引入了两个新函数可以用来实现CSPRNG: random_bytes 和 random_int。

    random_bytes 函数返回一个字符串,接受一个int型入参代表返回结果的字节数。

    例子:

    $bytes = random_bytes('10');
    var_dump(bin2hex($bytes));
    //possible ouput: string(20) "7dfab0af960d359388e6"

    random_int 函数返回一个指定范围内的int型数字。

    例子:

    var_dump(random_int(1, 100));
    //possible output: 27

    后台运行环境

    以上函数的随机性不同的取决于环境:

    在window上,CryptGenRandom()总是被使用。 在其他平台,arc4random_buf()假如可用会被使用(在BSD系列或者具有libbsd的系统上成立) 以上都不成立的话,一个linux系统调用getrandom(2)会被使用。 假如还不行,/dev/urandom 会被作为最后一个可使用的工具 假如以上都不行,系统会抛出错误

    一个简单的测试

    一个好的随机数生成系统保证合适的产生“质量”。为了检查这个质量, 通常要执行一连串的统计测试。不需要深入研究复杂的统计主题,比较一个已知的行为和数字生成器的结果可以帮助质量评价。

    一个简单的测试是骰子游戏。假设掷1个骰子1次得到结果为6的概率是1/6,那么假如我同时掷3个骰子100次,得到的结果粗略如下:

    0 个6 = 57.9 次 1 个6 = 34.7次 2 个6 = 6.9次 3 个6 = 0.5次

    以下是是实现实现掷骰子1,000,000次的代码:

    $times = 1000000;
    $result = [];
    for ($i=0; $i<$times; $i++){
        $dieRoll = array(6 => 0); //initializes just the six counting to zero
        $dieRoll[roll()] += 1; //first die
        $dieRoll[roll()] += 1; //second die
        $dieRoll[roll()] += 1; //third die
        $result[$dieRoll[6]] += 1; //counts the sixes
    }
    function roll(){
        return random_int(1,6);
    }
    var_dump($result);

    用PHP7 的 random_int 和简单的 rand 函数可能得到如下结果

    Sixes expected random_int
    0 579000 579430
    1 347000 346927
    2 69000 68985
    3 5000 4658

    假如先看到rand 和 random_int 更好的比较我们可以应用一个公式把结果画在图上。公式是:(php结果-期待的结果)/期待结果的0.5次方。

    结果图如下:

    test random graph

    (接近0的值更好)

    尽管3个6的结果表现不好,并且这个测试对实际应用来说太过简单我们仍可以看出 random_int 表现优于 rand.

    进一步,我们的应用的安全级别由于不可预测性和随机数发生器的可重复行为而得到提升。

    PHP5 呢

    缺省情况下,PHP5 不提供强壮的随机数发生器。实际上,还是有选择的比如 openssl_random_pseudo_bytes(), mcrypt_create_iv() 或者直接使用fread()函数来使用 /dev/random 或 /dev/urandom 设备。也有一些包比如 RandomLib 或 libsodium.

    假如你想要开始使用一个更好的随机数发生器并且同时准备好使用PHP7,你可以使用Paragon Initiative Enterprises random_compat 库。 random_compat 库允许你在 PHP 5.x project.使用 random_bytes() and random_int()

    这个库可以通过Composer安装:

    composer require paragonie/random_compat
    require 'vendor/autoload.php';
    $string = random_bytes(32);
    var_dump(bin2hex($string));
    // string(64) "8757a27ce421b3b9363b7825104f8bc8cf27c4c3036573e5f0d4a91ad2aaec6f"
    $int = random_int(0,255);
    var_dump($int);
    // int(81)

    random_compat 库和PHP7使用不同的顺序:

    fread() /dev/urandom if available
    mcrypt_create_iv($bytes, MCRYPT_CREATE_IV)
    COM('CAPICOM.Utilities.1')->GetRandom()
    openssl_random_pseudo_bytes()

    想知道为什么是这个顺序建议阅读 documentation.

    这个库的一个简单应用用来产生密码:

    $passwordChar = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $passwordLength = 8;
    $max = strlen($passwordChar) - 1;
    $password = '';
    for ($i = 0; $i < $passwordLength; ++$i) {
        $password .= $passwordChar[random_int(0, $max)];
    }
    echo $password;
    //possible output: 7rgG8GHu

    总结

    你总是应该使用一个密码学上安全的伪随机数生成器,random_compat 库提供了一种好的实现。

    假如你想要使用可靠的随机数据源,如你在本文所见,建议尽快使用 random_int 和 random_bytes.

    上一篇返回首页 下一篇

    声明: 此文观点不代表本站立场;转载务必保留本文链接;版权疑问请联系我们。

    别人在看

    正版 Windows 11产品密钥怎么查找/查看?

    还有3个月,微软将停止 Windows 10 的更新

    Windows 10 终止支持后,企业为何要立即升级?

    Windows 10 将于 2025年10 月终止技术支持,建议迁移到 Windows 11

    Windows 12 发布推迟,微软正全力筹备Windows 11 25H2更新

    Linux 退出 mail的命令是什么

    Linux 提醒 No space left on device,但我的空间看起来还有不少空余呢

    hiberfil.sys文件可以删除吗?了解该文件并手把手教你删除C盘的hiberfil.sys文件

    Window 10和 Windows 11哪个好?答案是:看你自己的需求

    盗版软件成公司里的“隐形炸弹”?老板们的“法务噩梦” 有救了!

    IT头条

    公安部:我国在售汽车搭载的“智驾”系统都不具备“自动驾驶”功能

    02:03

    液冷服务器概念股走强,博汇、润泽等液冷概念股票大涨

    01:17

    亚太地区的 AI 驱动型医疗保健:2025 年及以后的下一步是什么?

    16:30

    智能手机市场风云:iPhone领跑销量榜,华为缺席引争议

    15:43

    大数据算法和“老师傅”经验叠加 智慧化收储粮食尽显“科技范”

    15:17

    技术热点

    商业智能成CIO优先关注点 技术落地方显成效(1)

    用linux安装MySQL时产生问题破解

    JAVA中关于Map的九大问题

    windows 7旗舰版无法使用远程登录如何开启telnet服务

    Android View 事件分发机制详解

    MySQL用户变量的用法

      友情链接:
    • IT采购网
    • 科技号
    • 中国存储网
    • 存储网
    • 半导体联盟
    • 医疗软件网
    • 软件中国
    • ITbrand
    • 采购中国
    • CIO智库
    • 考研题库
    • 法务网
    • AI工具网
    • 电子芯片网
    • 安全库
    • 隐私保护
    • 版权申明
    • 联系我们
    IT技术网 版权所有 © 2020-2025,京ICP备14047533号-20,Power by OK设计网

    在上方输入关键词后,回车键 开始搜索。Esc键 取消该搜索窗口。