• 伪随机数的爆破--1


    伪随机数的爆破–1

    伪随机数的爆破–1

    1 简介

    关于伪随机数生成器的相关知识,参考解密随机数生成器

    Java.util.Random采用的是线性同余法生成伪随机数,种子是48位的,而Random.nextInt返回的是32位数字:next(32)。如下代码,直接是nextSeed右移16位的结果。

    protected int next(int bits) {
        long oldseed, nextseed;
        AtomicLong seed = this.seed;
        do {
            oldseed = seed.get();
            nextseed = (oldseed * multiplier + addend) & mask;
        } while (!seed.compareAndSet(oldseed, nextseed));
        return (int)(nextseed >>> (48 - bits));
    }
    

    因此,只要知道两个连续的nextInt值,便可以通过暴力猜解丢失的前18位来获得种子。

    2 具体实现

    参考cracking random number generators的实现:

    ;; 常数定义和算法都取自java.util.Random类
    (def multiplier 0x5DEECE66D)
    (def addend 0xB)
    (def mask (dec (bit-shift-left 1 48)))
    
    (defn next-seed
      [seed]
      (bit-and
       (+ (unchecked-multiply seed multiplier)
          addend)
       mask))
    
    (defn next-int
      [seed]
      (-> (next-seed seed)
          (unsigned-bit-shift-right 16)
          unchecked-int))
    
    (defn brute-seed
      "只要有两个连续的randInt值就可以非常快的爆破出种子"
      [v1 v2]
      (loop [i 0]
        (when (< i 65536)
          (let [seed (+ i
                        (* v1 65536))
                test-v (next-int seed)]
            (if (= test-v v2)
              seed
              (recur (inc i)))))))
    
    ;;; 以下为测试代码
    (def rnd (java.util.Random.))
    (def rnd-v1 (.nextInt rnd))
    (def rnd-v2 (.nextInt rnd))
    
    rnd-v1
    ;; => -1680039525
    rnd-v2
    ;; => -1809533376
    
    (def seed (brute-seed rnd-v1 rnd-v2))
    seed
    ;; => -110103070270234
    
    ;; 获得下一个随机值
    (-> (next-seed seed)
        next-int)
    ;; => 796622690
    
    ;; 与生成的随机值比较,可以看到正确的获取到了下一个Int值
    (.nextInt rnd)
    ;; => 796622690
    
    ;; 再测试下下个
    (-> (next-seed seed)
        next-seed
        next-int)
    ;; => -52712848
    
    (.nextInt rnd)
    ;; => -52712848
    

    3 结尾

    猜测216还是很快的.

    但对于nextInt(int bound)的调用,由于信息损失较多,就不大可能直接猜解出来,要爆破248速度还没那么快。下一篇是关于php mt_rand的讲解。

    作者: ntestoc

    Created: 2019-03-16 周六 21:31

  • 相关阅读:
    beautiful number 数位DP codeforces 55D
    最长上升子序列
    0-1背包 codeforces 55 D
    概率DP HDU 4586 play the dice
    水题 不要62 HDU 2089
    抓老鼠 codeForce 148D
    ZOJ 3551 吸血鬼 概率DP
    poj 2151 Check the difficulty of problems 概率DP
    HDU 4681 string 求最长公共子序列的简单DP+暴力枚举
    HDU 1814 模板题 2-sat
  • 原文地址:https://www.cnblogs.com/ntestoc/p/10535267.html
Copyright © 2020-2023  润新知