• 流密码:线性同余生成器 LCG


    本节作为流密码第一篇科普性文章,首先介绍一下什么是流密码。

    什么是流密码?

    在介绍流密码之前,我们先引入OTP(One-time Password,一次性密码)这样一个概念。
    所谓一次性密码,是一次加密使用一次密钥,这次加密过程中使用的密钥不能在下一次加密中继续使用,密钥是一次性的,使用一次当即作废。

    例如:
    我们想加密 abcdefg 这串字符。想要加密所有明文,就要用与明文等长的密钥来加密。比如利用密钥1234567加密,1代表在字母表的顺序向后移动一位,2代表移动2位,等等,和凯撒的原理相同,只不过这里使用了多个密钥。

    但是,我们会遇到这样一个问题,我们需要用和明文长度相同的密钥来去加密明文,然后需要将密文与密钥一同发送给对方,对方才能用密钥来解密密文,在这个过程中,密钥是不可泄露的,因此我们又需要一个十分安全的方式来护送密钥。
    那么,既然密钥长度和明文一样,也就是护送的难度一样大,如果真的有一种方法可以安全的护送密钥,为什么不直接用这种安全的方式来护送明文呢?

    显然,OTP在实际操作中效率并不高,我们也许可以用一个比较短的密钥来加密明文呢?

    例如,我们选择123作为密钥,加密的时候,可以重复使用密钥,例如1231231作为密钥来加密abcdefg。但是,这样的重复列太容易被破解了,我们需要让123生成的7位密钥看似杂乱无章一点,无序一点,比如1239782,看起来像随机数一样,这样既减小了护送密钥的难度,也能提高其加密的安全性。

    流密码,应运而生。

    LCG(线性同余生成器)

    LCG既属于伪随机数发生器,也属于流密码。因为他的生成既达到了随机数生成的要求,又能按照需求将一定长度的内容扩展到需要的长度。

    LCG原理:
    S n + 1 = a ∗ S n + b   ( m o d   m ) S_{n+1}=a*S_n+b~(mod~m)\\ Sn+1=aSn+b (mod m)
    其中,m表示模量、a表示乘数、b表示增量。

    同时要求 g c d ( m , a ) = 1 gcd(m,a)=1 gcd(m,a)=1
    周期 T = O r d m ( a ) T=Ordm(a) T=Ordm(a)
    为了让周期尽可能的大,我们需要让a尽可能的是m的一个原根,这时周期最大,为 ϕ ( m ) \phi{(m)} ϕ(m)
    有关原根的理解可以参考下面这篇博客:
    https://blog.csdn.net/qq_44109982/article/details/111324293

    ATTACK

    当我们知道了由LCG生成的连续三个随机数时,就可以破解LCG
    S n = a ∗ S n − 1 + b   ( m o d   m ) S n + 1 = a ∗ S n + b   ( m o d   m ) S_n=a*S_{n-1}+b~(mod~m)\\ S_{n+1}=a*S_n+b ~(mod~m) Sn=aSn1+b (mod m)Sn+1=aSn+b (mod m)
    下式减上式,得到:
    S n + 1 − S n = a ∗ ( S n − S n − 1 )   ( m o d   m ) S_{n+1}-S_n=a*(S_n-S_{n-1})~(mod~m) Sn+1Sn=a(SnSn1) (mod m)
    只有a已知,我们可以求出来a,带入上面的式子求出b,那么我们只要知道一个随机数,就可以知道它的下一个随机数是多少了。


    当然,结合到数学问题,再ctf中还会存在多种解题姿势。
    例如,给出给出四个连续的已知随机数:
    T n = S n + 1 − S n   ( m o d   m ) T n + 1 = S n + 2 − S n + 1   ( m o d   m ) = a ( S n + 1 − S n )   ( m o d   m ) = a T n   ( m o d   m ) T n + 2 = S n + 3 − S n + 2   ( m o d   m ) = a T n + 1   ( m o d   m ) = a 2 T n   ( m o d   m ) T_{n}=S_{n+1}-S_{n}~(mod~m)\\ T_{n+1}=S_{n+2}-S_{n+1}~(mod~m)=a(S_{n+1}-S_{n})~(mod~m)=aT_n~(mod~m)\\ T_{n+2}=S_{n+3}-S_{n+2}~(mod~m)=aT_{n+1}~(mod~m)=a^2T_n~(mod~m) Tn=Sn+1Sn (mod m)Tn+1=Sn+2Sn+1 (mod m)=a(Sn+1Sn) (mod m)=aTn (mod m)Tn+2=Sn+3Sn+2 (mod m)=aTn+1 (mod m)=a2Tn (mod m)
    所以:
    T n ∗ T n + 2 = a 2 T n 2 = T n + 1 2 T_n*T_{n+2}=a^2T_n^2=T_{n+1}^2 TnTn+2=a2Tn2=Tn+12
    所以 T n + 2 ∗ T n − T n + 1 2 = k ∗ m T_{n+2}*T_n-T_{n+1}^2=k*m Tn+2TnTn+12=km
    则易找到m

  • 相关阅读:
    redis基础3——配置文件核心参数实测+RDB持久化、AOF持久化核心参数详解
    万亿数据秒级响应,Apache Doris 在360 数科实时数仓中的应用
    webpack做HTTP压缩
    Python爬虫——爬取某网站的视频
    想学python找不到合适的书籍?它来了!入门python只需要这一本书就够了!
    Facebook账号复审的问题。
    手把手教你彻底卸载MySQL
    故障009:改写多表关联同时更新且互换列值
    Canal整合SpringBoot详解(一)
    大模型都在用的:旋转位置编码
  • 原文地址:https://blog.csdn.net/m0_62506844/article/details/126001653