随机函数用于加密——重排法

来源:互联网 发布:c语言编程入门软件 编辑:程序博客网 时间:2024/06/07 23:21

一般的成见是随机函数不能用于信息加密,不能作为密钥来加密文件。在没有好的方法之前这些观念也许是对的。但事实未必如此,如果能够克服随机函数自身的缺陷,用于加密应该是没有问题的,这里将探索几种方法这是其一。下面介绍应用随机函数加密的方法之一“重排法”。
“重排法”原理很简单,就是先用随机函数生成序列数组,然后对数组的顺序进行重新排列,如何进行重排?可以仍然用这个函数进行随机排序,也可以用其它随机函数,甚至可以序列自身。“重排”的效果是什么?可以想象原来的序列不复存在了,原来随机函数的规律没有了,新的规律是什么?是来自排序的方式。然后用新的序列作为密钥去加密文件。在第一步用随机函数生成序列数组,使用和用户密码相关的参数作为随机函数的种子,同样使用和用户密码相关的参数作为排序时随机函数的种子,并且最终得到密钥串和文件串运算时也要用和用户密码相关的数据作为参数。用户密码对破解者来说是未知数,它在加密、解密过程中至关重要,它本身不可过于简单,否则后面的运算都受影响,直接影响加密的质量,所以加密程序要限定用户密码的长度。
首先看看用分析法能否破解,假定只使用一个随机函数,它的周期是T,现在我们不知道形成初始串的起点在哪里,要找到起点可能要做T次试验,另外用于随机排序的起点也不知道,要找到起点可能也要做T次试验,这样综合起来可能要做的试验就是T×T了。就是得到了密钥串,如何与明文串进行运算?由于和用户密码相关的参数不知道,只能通过实验来尝试,假如参数1的取值范围是N1,参数2的取值范围是N2等,这样需要做的试验就是T×T×N1×N2×L了,L是文件的长度。做了试验如何判断破解是否成功?可以分许多情况,也许你本来就知道结果,也许知道文件的类型,也许什么也不知道,一般是需要分析上下文来判断的,很不容易的,如果明文本身就是乱码,那根本就没有依据判断,也就无法破解。假如随机函数的周期T是10的18次方数量级的,可见试验数量是天文数字,根本无法完成。
再看看靠穷举用户密码的情况,程序运行后显示效验码,首先让用户仿照输入这些效验码,这些效验码以图形方式出现,效验码字符由于采用扭曲变形、杂色、交叉等方式计算机不能有效识别读出这些字符,但用户可以通过联想判断读出效验码,这样就排除了自动运行的穷举攻击,而且效验码也许不止出现在开始,也许出现在其它运算过程中,如果没有人为的干预,是不能进行下去的。勉强输入少量的试解密码,也同样碰到判断解密成功的困难,程序不会为你筛选密码,只要输入格式、密码字节数限制等规则符合要求就开始解密运算了,密码不对当然不能得出正确的结果,并且密文被破坏掉了。由于密码的取值范围是天文数字,加之各种阻碍在有限的时间里不可能完成计算。并且程序有监测功能,如果发现你总是对某个密文进行解密操作超过一定次数它将退出运行。所以穷举法这条路也走不通的。
此种方法的缺陷之一是加密速度较慢,大约每秒2M-16M字节,因为周期大的随机函数运算复杂,多次调用的缘故。
方法新出难免有各方面的漏洞,希望指正。
已经用上述主要方法做成文件加密的试验程序,在http://c.thec.cn/sjdclw/试验程序-1.rar可以下载试用。看看你能够解出用它加密的文件吗?
试验程序使用的随机函数如下(C语言定义)。
第一个周期大约是4.29×10的9次方。
#define MUL 0x015a4e35L
#define INC 1
static long Seed=1;
void sranda(long seed);
int randa(void);

void sranda(long seed)                           //随机函数的种子函数
{
 Seed=seed;
}
int randa(void)                                  //随机函数
{
 Seed=MUL*Seed+INC;
 return((int)(Seed>>24));
}
这个随机函数算法比较简单,所以速度较高,超过每秒16M字节。