流密码的密钥

来源:互联网 发布:sql语句怎么修改列名 编辑:程序博客网 时间:2024/06/02 09:48

  这里讨论的主要是用于文件加密的情况,而不是用于实时通讯加密。
  现在一般流密码的密钥形成是:由线性移位寄存器(LFSR)和一个非线性组合函数,即布尔函数组合,构成一个密钥流生成器。由于LFSR和非线性函数都是比较固定的东西,所以生成的密钥缺乏灵活性多次使用容易被破译,它的保密性依赖于LFSR和非线性函数的保密,并且密钥流中的数据不是独立的而是相关的,所以保密性不强容易被分析破解。
  这里尝试不用LFSR和非线性组合函数,只用随机函数,并要求密钥流中的数据完全独立。
  一般文件都是以字节为单位的数据集合,为不失一般性这里的密钥流也都以字节为单位。
  这里建造密钥流的目的是用于文件加密,所以用户密码作为重要参数在这里起着至关重要的作用。
  这里对密钥流的要求是:易控制、易于产生、随机性好、算法公开、数据之间不相关,不容易被分析跟踪。
  下面以实例说明如何建造流密码密钥。我们知道随机函数易于产生,好的随机函数生成的随机数序列可以通过各项相关的检测,但由于出自同样的公式数据之间是有内在联系的、数据之间不是独立的,所以不能直接用作流密钥。我们选择两个好的随机函数(能通过各项检测)Rand1和Rand2,它们的值域是4字节整形数也就是32bit二进制数,周期是T1、T2且越长越好,例如需要建造长度为N的流密钥单位是字节也就是8bit二进制数,用户密码一般是多个ASCII码组成,我们需要用它来衍生一些数据供下面的计算使用,方法很多这里的方法是:计算用户密码字符组合的32位CRC值,例如所有字符的CRC值,所有字符倒序排列的CRC值,前三个字符的CRC值等等,这样我们就有了和用户密码相关的参数值这里统称为密码相关参数,首先用密码相关参数作为随机种子利用Rand1生成N个数,再取一个大于256的32Bit的密码相关参数作为模,对前面N个数做取模运算也就是取余数,并装入字节数组,这样就形成了初始的数组,接下来是对这个数组进行加工使数组成员之间没有任何联系,方法很简单就是利用Rand2对初始数组进行随机排序彻底颠覆原来的数据结构,这里也需要用密码相关参数做随机种子,方法很多仅举一例,做法是对N个数进行循环,循环到第i个序号,用i序号对应的元素和Rand2计算出的序号所对应的元素进行数值交换,从而达到新的排序,由此产生出新的数组。排序操作可以进行多次,越多复杂性越高,就看有没有必要了。
  上面简单的说明流密钥的建造,所用到的随机函数及所有算法和操作过程都可以公开。现在要从流密钥数组找出用户密码,假如我们知道流密钥数组,现在想知道用户密码。当然可以用穷举法,你可以仿造上面的过程建造一个生成数组的程序,然后用不同的密码去试验,并通过比较结果而得到密码,如果密码较长这是个很费时间的过程。下面看看用分析法所遇到的困难,跟踪生成初始数组可能需要做T1×(32位整形数数域)大约是T1×4.29×10的9次方,这是需要在T1范围寻找和那个模运算(取余数运算)的共同结果,排序需要在T2范围寻找,所以总的试验次数为T1×T2×4.29×10的9次方,如果T1和T2都是10的20次方数量级的,则试验数将达到10的49次方数量级,当前计算机极限运算速度是每秒5000万亿次浮点运算,也就是5×10的15次方次浮点运算,假设可以每秒做如此多次试验,则需要做2×10的33次方秒大约6×10的25次方年,可见大大超过与宇宙寿命240亿年了,这只是一遍排序的情况,两遍试验数就要再乘上10的20次方。
  如此产生的流密钥对不能溯源的人来说是真随机数,真随机数实际上是个相对概念,即便是采自物理现象的真随机数组一经公布也不再是真随机数组了,因为凡是对其备份的人都有可能再现它,而真随机数组是不能重复出现的。再者流密钥只是加密过程中的产物是不可见的,是隐含在密文流中的,所以对能够控制它的人来说是伪随机数组,而对不能控制它的人来说是真随机数组。
  当用户密码足够长时,才具有抗攻击性,极端的例子用户密码只有一位二进制数,只能取0或1就无密可保了。可以粗略的估算一下,例如用到的随机函数的周期是10的18次方数量级的,那么用户密码至少应有8个字符才可能够用(当然还要看怎么用了)。
  穷举攻击并不可怕,可怕的是加密软件本身为穷举攻击提供了便利(参见[文件加密与自毁长城 })。如果不提供方便穷举攻击和分析攻击一样面对无穷大的时间考验。

原创粉丝点击