• 伪随机数安全性


    真正的随机数是使用物理现象产生的:比如掷钱币、骰子、转轮、使用电子元件的噪音、核裂变等等。这样的随机数发生器叫做物理性随机数发生器,虽然很可靠,但是使用计算机很难实现,它们的缺点是技术要求比较高。
    在实际应用中往往使用伪随机数就足够了。这些数列看似是随机的数,实际上它们是通过一个固定的、可以重复的计算方法产生的。计算机产生的随机数有很长的周 期性。它们不真正地随机,因为它们实际上是可以计算出来的,但是它们具有类似于随机数的统计特征。这样的发生器叫做伪随机数发生器。
    伪随机数又有强弱之分。强伪随机数一般是指相对难以猜解的随机数,比如服务器占用的内存数量作为随机数;而弱伪随机数是指相对容易猜解的随机数呢,典型的例子是当前的时间戳等。
    C、C++、Java等程序语言和软件中都有对应的随机数生成函数或者类。以我们最常用的Java语言为例,强伪随机数RNG实现 java.security.SecureRandom类,该类使用临时文件夹中大小,线程休眠时间等的值作为随机数种子;而弱伪随机数实现PRNG java.util.Random类,默认使用当前时间作为种子,并且采用线性同余法计算下一个随机数。

    Random r = new Random(10000); //10000作为seed,默认使用当前时间作为seed
    for (int i=0;i<5;++i)
    {
      System.out.println(r.nextInt());
    }

    以上这段代码,无论你怎么跑都会打印出以下结果:
    -498702880
     -858606152
     1942818232
    -1044940345
    1588429001
    这是一个稳定的结果。这就是由于线性同余法带来的后果。那么,在我们的程序,如果使用Random类生成一个随机数,事实上很容易通过上一个产生的随机数来推断下一个随机数。
    接下来,我们来分析一些常用的随机数应用场景,并且分析一下出错的原因。
    很多账号体系都有一个找回密码功能,找回密码时给手机发送的验证码,给邮箱发送的验证码或者重置密码链接,以上种种都使用了伪随机数。
    下面以某网站通过邮箱重置密码链接找回密码为例,通过页面操作之后,会在密保邮箱中发现以下重置密码的链接:
    http://www.xxx.com/findpwd/setpwdfromemail?vc=2ABB36620A927644607491393EF0D5EF&u=xxx%40gmail.com
    通过分析,我们发现,vc=2ABB36620A927644607491393EF0D5EF是一串md值,解开之后值是1339744000,是个 unix时间戳!那么可以猜测,用户取回密码时产生一个时间戳与帐号绑定,那么修改这个用户密码只需知道这个时间戳就可以。况且,一般服务器时间都是跟标 准时间同步,也就是说unix时间戳是可以预测的。我们可以通过暴力破解遍历当前标准时间+一个网络延迟来进行暴力破解。
    伪随机数的应用里,验证码是另外一种典型应用。对于安全而言,验证码是一个非常有效的保护机制和人机区分机制,可以保障口令不被暴力破解,可以防止刷票, 刷屏,重复提交恶意数据等。除了作为验证码之外,类似的应用还存在于一些活动的优惠券或者兑换码,如果兑换码设计不当,很容易被破解而破坏活动的公平性。
    总结一下,使用随机数的场景需要注意以下几点:
    不要使用时间戳作为随机数
    保证不同用处的随机数使用不同的种子
    对于安全性要求高的随机数,使用强伪随机数产生

  • 相关阅读:
    Android 监听键盘的弹起与收缩
    Android Glide+CircleImageView实现加载圆形图片列表
    Java 集合
    Java 文件IO续
    Java 文件IO
    Java 网络编程
    Android AIDL Service
    Android 四大组件之Service
    Android 开源项目分类汇总(转)
    Android SQLite数据库
  • 原文地址:https://www.cnblogs.com/longshiyVip/p/4707197.html
Copyright © 2020-2023  润新知