700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > PRNG伪随机数的破解方法

PRNG伪随机数的破解方法

时间:2018-05-26 12:30:03

相关推荐

PRNG伪随机数的破解方法

一、简单的PRNG算法简介

先简单的介绍一下PRNG伪随机数生成算法,网上的教程好多都好复杂,其实对于我们做这道题来讲用不到那么多,只讲最核心的就行:

原理公式:注意那个和,这个其实表示上一次生成的随机数会作用到下一次的随机数生成过程中。

写一段很简单的python代码:

seed=*****#初始随机数种子Randrom_Num=[] #生成的所有随机数for i in range(0,n): #表示生成n个随机数seed = (seed * a + b) % n #这个新的seed计算后就是生成的随机数Randr_Num.append(seed)

这就给了我们破解这类题的思路。见下面。

Crypto题目如下。

from Crypto.Util.number import bytes_to_long, getPrimefrom flag import flaga = getPrime(400)b = getPrime(400)n = getPrime(400)flag = bytes_to_long(flag)seed = flagresult = []for i in range(3):seed = (seed * a + b) % nresult.append(seed)print(result)print(n)"""[1633086272556604467630727869278140040711140555507257984778706962389364338237377391272504059109316040445365656669071569236, 120638905165679733692567537241269747788968914117438028996134855270953116218085368711678892215286522581909284859193494, 664238088423928246579566483655935746695807924062694495126404306361290788561253706421181510449476188038387172722467882193]2482696698513566590184292572066254640333143735400366745928208268241117181592178071999744746850718587310205478604372055081"""

二、解密过程

想要解密的话必须有连续生成的三个随机数和模数才可以。

三个随机数分别是lcd0,lcd1,lcd2。然后根据生成算法可得下面的一个方程组。

lcg1=(a*lcg0+c)%m

lcg2=(a*lcg1+c)%m

两式相减

左边为:lcg2-lcg1 右边为:(a*lcg1+c)-(a*lcg0+c)

化简为: [lcg2-lcg1=a*(lcg1-lcg0) ] %m

根据求余运算规则可知

[a=(lcg2-lcg1)*gmpy2.invert(lcg1-lcg0,m)]%m

此时代入lcg0,lcg1,lcg2之后可求得a

代入lcg1=(a*lcg0+c)%m,把c当作未知数放到等式左边后,式子为:

c=[lcg1-(a*lcg0)]%m

#如果怕自己解到的a,c是错的话可以带入第三个式子去试试。

# 类推lcg3_guess=(a*lcg2+c)%m

# 将求得地lcg3_guess与lcg3比较,如果相等,证明求得的a,c,m为正确值

# 否则,m=m+1,继续验证

而一般情况下会把flag当作lcd0输入,所以还需要我们解一元同余式来求最后的flag。

求解一元同余式的方法:照着公式编程就行。下面找的是一次同余式的通解,但是在ctf比赛中实际上只有一个flag,所以只有一个解,因此(a,m)就是1,这样编程的时候公式可以简略好多。

三.写出解密脚本

import gmpy2from Crypto.Util.number import bytes_to_long, getPrime, long_to_bytesn=2482696698513566590184292572066254640333143735400366745928208268241117181592178071999744746850718587310205478604372055081result=[1633086272556604467630727869278140040711140555507257984778706962389364338237377391272504059109316040445365656669071569236, 120638905165679733692567537241269747788968914117438028996134855270953116218085368711678892215286522581909284859193494, 664238088423928246579566483655935746695807924062694495126404306361290788561253706421181510449476188038387172722467882193]a=((result[2]-result[1])*gmpy2.invert(result[1]-result[0],n))%nb=(result[1]-(a*result[0]))%n#求解一元同余式得到flagflag=(((result[0]-b))*gmpy2.invert(a,n)+n)%nprint(long_to_bytes(flag))

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。