图3-1 文件大小--加密时间曲线(逐字节)
从表3-4以及图3-1可以看出,使用同一公开密钥加密不同大小的文件,消耗时间随着文件大小的增加线性的增加,和1.2.1小节分析的完全一致。对于较大的文件,加密位数对时间的影响十分明显。对于250字节的文件来说,1024bit的公钥加密比512bit的耗时多1.5倍左右;1024bit的私钥解密比512bit的耗时多3倍以上。对于一定的加密位数来说,私钥解密所需要的时间比公钥加密需要的时间长。对于一定大小的文件,使用512bit的密钥,私有密钥解密需要的时间是公开密钥加密需要时间的2倍左右;而如果使用1024bit的密钥,私有密钥解密需要的时间是公开密钥加密需要时间的3倍以上。再测试几个1280bit的密钥加解密,发现私有密钥解密所需要的时间相对于公钥加密时间更长。可见,本软件密钥长度越长,私有密钥解密与公开密钥加密的耗时比越大,这和其他软件是一致的。因为根据PCKS #1的RSA的应用建议,e是比较短的,而d和n的长度差不多,这就使得求与d、n有关的幂模运算量比与e、n有关的幂模运算量大很多,而且随着n的增加,两组幂模运算的运算量差距也迅速加大。为了减少d、n幂模运算的时间消耗,考虑到使用中国余数定理分解简化运算,具体做法见3.3节。
2. 用同样的密钥对不同大小的文件公钥加密,加密后生成的文件大小与待加密文件大小的关系
在上一组测试进行完之后,我们得到了一些加密文件,下面详细分析这些加密后生成的文本文件大小。表3-5给出了加密后的各文件大小。
表3-5 本软件生成的加密文件大小测试(文件大小单位:Byte)
n位数 文件大小 50Byte 100Byte 150Byte 200Byte 250Byte
512bit公钥加密 6,557 12,977 19,397 25,817 32,237
1024bit公钥加密 12,986 25,835 38,684 51,533 64,382
从表3-5的数据可以发现,对于同样的文件进行加密,使用1024bit密钥加密所得到的文件大小是使用512bit加密的2倍左右。而且不论用哪组密钥进行加密,加密所生成的文件大小都比原来未加密的文件大。可以从两个角度来理解文件在加密后增大:(1) 因为模数n通常较大,所以加密幂模运算的结果通常很大,这使得逐字节加密时,密文比明文长很多。(2) 因为加密完以后保存成十辣进制文本,对于十辣进制文本来说,每字节可能出现的字符只有16个,所以字节熵是4bit;而对于任意数据来说,每字节的熵是8bit。所以同样的信息量,采用十辣进制文本要比原始数据大一倍。从更简单的角度理解,每字节表示为两位十辣进制,每位十辣进制在文本中是一个符号,占用1字节,所以长度大了一倍。
从表3-5的数据还可以看出,对于同样的密钥,随着原始文件大小的线性增长,加密后的文件大小也基本呈线性增长。在使用512bit加密时,加密后的文件大小是加密前数据大小的130倍左右;在使用1024bit加密时,加密后文件大小是加密前数据大小的260倍左右。根据这些数据,可以总结出本软件使用的加密方式,加密前后文件大小的近似换算公式如下:
,
其中A是待加密文件数据长度,B是加密后文件长度,N是RSA加密位数,N>8。
以上公式其实也可以从理论上得到,因为模数n取8位时,幂模运算的结果仍然近似为8位,这时一个字节的数据经过加密,得到的数据大小近似不变,转换成十辣进制文本,大小就增加了1倍。按此原理,幂模运算结果长度近似为加密模数n的长度,加密后数据长度是加密前的N/8倍(N是加密位数),而转换为十辣进制文本后长度又增大1倍,加密后得到的文本长度就是加密前原始数据大小的N/4倍,所以B=A×N/4,这与前面从实验结果总结得到的公式基本一致,可以把公式中的260修正为更精确一些的256。
3. 以多字节为步长,对文件进行加密
默认的设置是加密时逐个字节进行RSA运算,可以通过设置窗体把分块的大小更改为其他长度,比如2字节一组、4字节一组,进行RSA运算。下面测试多字节为步长的加密执行效率。取一个480字节长的文件作为加密对象,对其进行512bit RSA公钥加密、私钥解密还原,记录所消耗的时间。统计数据如表3-6所示。
表3-6 加密分段大小改变对效率的影响测试(消耗时间单位:秒)
加密方式 步长 2字节 4字节 6字节 8字节 10字节
512bit公钥加密 23.5551 12.8205 7.8117 5.9185 5.1848
512bit私钥解密 46.3083 23.6089 16.1083 11.4820 9.2541
可见,增大加密步长使加密解密速度大幅增加,而且大步长的加密生成的文本文件体积也比小步长的小。这都是因为增大了步长后,文件被分成的块数少了,幂模运算次数下降。所以在使用RSA加密时,设置使用合适的数据分块也是提高加密速度的关键。
4. 在更快的PC,对进行文件加密测试
在一些性能更好的PC上,本软件可以获得更好的性能,测试数据同样可以分析得到以上段落叙述的结论。下面对照表3-4,给出一组其他PC上同样的测试得到的数据,测试PC配置为CPU AMD Athron2800+,外频333MHZ,物理内存512MB。数据见表3-7。
表3-7 待加密文件大小与加密时间的关系再次测试(时间单位:秒)
n位数 文件大小 50Byte 100Byte 150Byte 200Byte 250Byte
512bit公钥加密 2.4347 4.8975 7.1728 9.4508 11.9837
512bit私钥解密 4.7725 9.4427 14.002 19.0125 23.6544
1024bit公钥加密 6.3501 12.2364 18.2459 24.3001 30.1284
1024bit私钥解密 20.0101 39.8754 60.2126 79.3351 99.5482
对于这组数据,表3-4后的推理分析仍都成立。在此PC测试填写表3-6,同样得到了类似规律的数据,在此不再罗列。经过一系列各种机型、各种Windows操作系统(包括Windows XP/2000SP4/ME/98,均需.Net框架)上的测试,本软件均能正常运行。在2006年初主流配置的PC上运行此软件,逐字节加密1KB大小的文件,消耗时间均在1分钟以内。
3.2.4 性能分析与改进优化
经过一系列的RSA密钥生成、文件输入输出和加密解密测试,做简要的性能分析如下。
① 软件消耗时间的运算,大部分集中在C++核心类库,即RSA相关的各种运算。其中,幂模运算和寻找素数对时间的消耗最大,在核心优化时应优先考虑。
② 文件输入输出消耗时间其次,因为磁盘读写速度要远远低于内存读写速度。所以,应该将频繁的读写操作尽量集中到内存,然后一次性写入磁盘。
针对以上两点,软件应进行一系列改进和优化。主要有以下几方面。
① 在要对文件进行加密解密的时候,先将文件按一定的数据结构读入内存,然后进行加密或解密操作。运算数据都读取自内存。
② 在对加密或解密完成的数据进行写出的时候,都是将其直接写到指定好的文件,即直接写入磁盘。这是因为,考虑到中途可能因为意外断电等原因引起操作中断,为了保护已经花费时间运算完成的数据,将其直接写入磁盘。
③ 在关键算法上做进一步优化,例如在寻找素数时,素数测试使用更快速的算法;还有3.3节提到的,在用私有密钥进行幂模运算时使用中国余数定理等。
④ 对C++核心类库进行重点优化,使其运算效率尽可能提高。其中包括对各类之间的组织细节、各程序模块的具体编写等,进行全面细致的检查和修改,例如将大数据类型以对象指针传递而不拷贝,将简单的for循环展开等。
由于开发时间仓促等因素,在书写本文时,软件并未完成全面细致的优化。
上一页 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] ... 下一页 >>