[毕业设计 论文 精品]RSA文件加密软件的设计与实现.doc

上传人:laozhun 文档编号:3932714 上传时间:2023-03-28 格式:DOC 页数:36 大小:399KB
返回 下载 相关 举报
[毕业设计 论文 精品]RSA文件加密软件的设计与实现.doc_第1页
第1页 / 共36页
[毕业设计 论文 精品]RSA文件加密软件的设计与实现.doc_第2页
第2页 / 共36页
[毕业设计 论文 精品]RSA文件加密软件的设计与实现.doc_第3页
第3页 / 共36页
[毕业设计 论文 精品]RSA文件加密软件的设计与实现.doc_第4页
第4页 / 共36页
[毕业设计 论文 精品]RSA文件加密软件的设计与实现.doc_第5页
第5页 / 共36页
点击查看更多>>
资源描述

《[毕业设计 论文 精品]RSA文件加密软件的设计与实现.doc》由会员分享,可在线阅读,更多相关《[毕业设计 论文 精品]RSA文件加密软件的设计与实现.doc(36页珍藏版)》请在三一办公上搜索。

1、目 录前 言1第1章 RSA应用现状及应用于文件加密的分析21.1 RSA算法介绍与应用现状21.2 RSA应用于文件加密的分析31.2.1 文件加密使用RSA的可行性31.2.2 文件加密使用RSA的意义4第2章 RSA文件加密软件的设计与实现62.1 需求分析与总体设计62.1.1 功能分析62.1.2 工程方案选择72.2 各部分的设计与开发82.2.1 实现RSA加密算法的C+核心类库82.2.2 封装C+核心类库的DLL组件182.2.3 引用DLL的.Net类与实现文件操作功能的窗体应用程序19第3章 软件整体测试与分析改进203.1 编写测试各项性能需要的精确计时类203.2 测

2、试数据与分析改进203.2.1 密钥生成测试203.2.2 数据输入输出测试233.2.3 加密解密测试233.2.4 性能分析与改进优化263.3 使用中国余数定理27第4章 可移植模块的简要说明与开发前景29结束语30谢 辞31参考文献32附 录33前 言RSA公钥加密算法是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也十分流行。算法的名字以发明者的姓氏首字母命名:Ron Rivest, Adi Shamir 和Leonard Adleman。虽然自1978年提出以来,RSA的安全性一直未能得到理论上的证明,但它经历了各种攻击,至今(2006年)未被完全攻破。随着越来越

3、多的商业应用和标准化工作,RSA已经成为最具代表性的公钥加密技术。VISA、MasterCard、IBM、Microsoft等公司协力制定的安全电子交易标准(Secure Electronic Transactions,SET)就采用了标准RSA算法,这使得RSA在我们的生活中几乎无处不在。网上交易加密连接、网上银行身份验证、各种信用卡使用的数字证书、智能移动电话和存储卡的验证功能芯片等,大多数使用RSA技术。当今公钥加密更广泛应用于互联网身份认证,本课题将公钥加密算法RSA应用于小型文件加密。将任意文件加密成文本的解决方案,使其使用更加灵活。整个工程的分层设计,给引用移植和后续开发带来便利。

4、第1章 RSA应用现状及应用于文件加密的分析1.1 RSA算法介绍与应用现状RSA算法可以简单叙述如下:取素数p,q,令n=pq.取与(p-1)(q-1)互素的整数e,由方程de=1 (mod (p-1)(q-1)解出d,二元组(e,n)作为公开密钥,二元组(d,n)作为私有密钥b=ae mod n,c=bd mod n.附录中给出了证明a=c (mod n).(具体的RSA算法协议见http:/www.di-.au/rsa_alg.html ,提及的算法中的字母与协议文档中的一致,不再另做解释)RSA公开密钥加密算法自20世纪70年代提出以来,已经得到了广泛认可和应用。发展至今,电子安全领域

5、的各方面已经形成了较为完备的国际规范。RSA作为最重要的公开密钥算法,在各领域的应用数不胜数。RSA在硬件方面,以技术成熟的IC应用于各种消费类电子产品。RSA在软件方面的应用,主要集中在Internet上。加密连接、数字签名和数字证书的核心算法广泛使用RSA。日常应用中,有比较著名的工具包Open SSL(SSL,Security Socket Layer,是一个安全传输协议,在Internet上进行数据保护和身份确认。Open SSL是一个开放源代码的实现了SSL及相关加密技术的软件包,由加拿大的Eric Yang等发起编写的。相关详细介绍见http:/www.openssl.org/ab

6、out/ )。Open SSL应用RSA实现签名和密钥交换,已经在各种操作系统得到非常广泛的应用。另外,家喻户晓的IE浏览器,自然也实现了SSL协议,集成了使用RSA技术的加密功能,结合MD5和SHA1,主要用于数字证书和数字签名,对于习惯于使用网上购物和网上银行的用户来说,几乎天天都在使用RSA技术。RSA更出现在要求高度安全稳定的企业级商务应用中。在当今的企业级商务应用中,不得不提及使用最广泛的平台j2ee。事实上,在j2se的标准库中,就为安全和加密服务提供了两组API:JCA和JCE。 JCA (Java Cryptography Architecture)提供基本的加密框架,如证书、

7、数字签名、报文摘要和密钥对产生器; JCA由几个实现了基本的加密技术功能的类和接口组成,其中最主要的是java.security包,此软件包包含的是一组核心的类和接口,Java中数字签名的方法就集中在此软件包中。JCE(Java Cryptography Extension) 在JCA的基础上作了扩展,JCE也是由几个软件包组成,其中最主要的是javax.crypto包,此软件包提供了JCE加密技术操作API。javax.crypto中的Cipher类用于具体的加密和解密。在上述软件包的实现中,集成了应用RSA算法的各种数据加密规范(RSA算法应用规范介绍参见: ,这些API内部支持的算法不仅

8、仅只有RSA,但是RSA是数字签名和证书中最常用的),用户程序可以直接使用java标准库中提供的API进行数字签名和证书的各种操作。单机应用程序使用RSA加密尚比较少见,例如使用RSA加密任意一个文件。1.2 RSA应用于文件加密的分析1.2.1 文件加密使用RSA的可行性通过1.1节的论述,不难看出RSA当今的应用多在于数字签名和证书等方面。之所以只应用于这些短小数据的加密解密,是因为RSA算法加密极慢,速度是DES对称密钥加密速度的千分之一左右。正是因为这样,把RSA应用于普通文件加密的想法一直被忽略。通常文件被想象成大数据块,但是实际上在日常应用中,有些极其重要的文本资料是并不太大的,比

9、如因担心遗忘而用普通文本记录的银行帐号和密码、不应被陌生人知道的重要电话号码、几千字节大的重要小图片等。虽然RSA加密运算的速度十分慢,但是在PC性能越来越好的今天,对于几千字节的数据进行一次几百位密钥的RSA加密,所消耗的时间应该是可以接受的。下面结合大数运算程序的调试,从理论上简单的分析消耗时间。在一台普通配置的PC机上对一个整数进行幂模运算,因为公开密钥的e通常取的较小,所以指数取一个小整数,比如C353,模一个70字节长的整数(140位十六进制,大数单元以线性组方式实现,对应到RSA算法中,这相当于约560bit的n),调试一个函数测试,按初等数论中的知识对程序进行算法优化,最终在一台

10、配置为AMD Athron2800+,外频333MHZ,物理内存512MB的PC上测试需要约45毫秒时间。如果按这种速度,逐字节对1KB的数据进行同样的运算,所消耗的时间理论上为45毫秒的1024倍即约45秒。这个时间并不是非常长。其实从一个简单的角度来说,既然RSA用于数字签名可行,那就完全可以用于同样大小的普通文件。对于较大的文件,如果分成与数字签名同样大小的段(这里假设数字签名较短,不分段一次计算加密完成),分开的各段逐一进行加密运算,那所需要的时间也只是按文件大小线性的增长。通常数字签名为几十字节,加密运算并不需要很长的等待,这就说明对于几百字节或一两K字节大小的文件来说,如果进行RS

11、A加密,并不会是非常漫长的工作。当然,如果文件更大,加密就显得十分漫长了。比如按前面叙述的45毫秒大数运算程序推理,加密1M字节大小的文件需要约1天的时间。所以,要在普通PC用几百位以上的长密钥RSA加密文件,文件不能过大,一般可以接受的上限是几KB。如果要在较短时间内加密大文件,需要缩短密钥长度以减小运算量,这将带来安全性隐患。本文的第3章将根据实际调试好的软件,测试给出具体的时间消耗数据。例如,在一台配置为AMD Athron2800+,外频333MHZ,物理内存512MB的PC上测试实现的软件,以560bit的n逐字节加密一个1KB大小的文件需要55秒。通常记录如银行帐号密码等重要数据的

12、文本文件大小不足百字节,加密只需要数秒钟。所以对于小型文件,进行较长密钥的RSA加密是完全可行的。1.2.2 文件加密使用RSA的意义如1.2.1节所述,小型文件加密可以使用RSA。比如,因担心遗忘而用普通文本记录的银行帐号和密码、不应被陌生人知道的重要电话号码、几千字节大的重要小图片等。可行的方法未必是必要的,本小节讨论何种文件适合用非对称密钥加密,即RSA加密文件的意义所在。对于前面叙述的带有重要信息的小型文本和二进制数据的维护,如果不加密,将无法放心的保存在计算机上,尤其是连网的或机房里的公共计算机。如果借助功能强大的大型多用户数据保护程序维护几个小型文件,显得十分烦琐,好比杀鸡用牛刀。

13、如果采用对称密钥加密,即加密解密的密钥相同,只适合部分情况。在某些情况下,使用对称密钥加密文件,交流使用不够方便。比如,张三由于某种原因,需要将自己的某个文件在公共计算机上留给李四,而不希望别人看到内容。如果采用对称密钥加密,张三和李四提前约好一个密码就可以。但是如果张三想要在同一台公共计算机上再留一个秘密文件给王五,而不希望别人看到,就要和王五另外约定一个密码。如果需要在这台公共计算机上留十个文件给不同的人,自己就要记和十个人约定好的密码,这样以来交流起来不够方便,因为对于张三,要自己维护太多的密钥。非对称密钥(公开密钥方式)恰好解决这样的问题。只要大家都在这台计算机或这台计算机可以访问到的

14、地方,留下自己的公开密钥,一切就变的容易解决了。张三要留给李四的文件,就用李四的公开密钥加密,要留给王五的文件,就用王五的公开密钥加密。李四和王五只要把留给自己的文件用自己的私有密钥解密,就可以得到留给自己的文件了。显然,非对称密钥体制更适合多用户交流,而将这种加密方式直接应用于文件加密,使我们在公开场合的交流更加灵活方便。一种更实际的情况是,我们想通过Internet上的公众论坛或邮件发送重要保密信息给某人。例如发送一个银行帐号和密码给某人。这种情况要保证安全,在当今互联网络上是比较棘手的。如果用公众论坛直接留言给指定用户,论坛管理员和服务器管理员通常有方法看到数据。如果发送邮件,虽然传送过

15、程是加密的,但是密码毕竟是由邮件服务器维护,所以系统管理员通常也有办法看到内容。问题的关键在于我们所有的数据包括密钥保存在服务器之上。在这种情况下,我们需要使用公开密钥方式,并自己维护私有密钥。RSA文件加密可以灵活的解决这些问题。例如,我们可以将任意一个文件用某人的公开密钥加密变换成一段可以复制粘贴的文本,然后粘贴在公众互联网上,对方只需把需要解密的文本复制保存成一个文本文件,在本地机用自己的私有密钥解密即可。我们可以将自己的私有密钥通过DES加密后保存在自己的移动磁盘上,使用的时候只要将其解密读取即可,用完后立即从当前操作环境清除。这样,我们自己维护自己的私有密钥,利用简单并且公开的方式,

16、可以安全传送任意小型数据,包括一切二进制文件。所以,对于使用小型文件进行数据交换的情况,更好的方案是通过一个小型应用程序对这些文件进行非对称密钥加密。为了适合前面叙述的在公共BBS与特定的某人交流重要保密信息的情况,加密生成的数据应该是文本,这样可以方便复制粘贴。综上所述,使用前面叙述的方式加密文件有两点重要意义:应用非对称密钥加密任意文件,使非对称密钥的应用不仅仅局限于互联网络。非对称加密后的数据变换成文本,使得我们可以通过几乎任何方式安全传递任意文件,比如在只有http的环境使用xml方式。第2章 RSA文件加密软件的设计与实现2.1 需求分析与总体设计2.1.1 功能分析经过1.2.2节

17、的论述,我们可以将对软件的要求总结如下:可以按要求的位数生成非对称密钥。可以保存密钥和装载密钥,密钥保存为纯文本。可以用指定密钥以RSA算法加密任意一个文件,加密生成的数据为纯文本。可以装载加密过的文件,并用指定的密钥解密还原出原文件。提示信息完整、操作舒适、图形界面雅观按上述描述,给出Use Case和Statechart如图2-1。图2-1 本项目的 Use Case和Statechart根据以上分析,一般来说,需要进行编码的程序有 RSA密钥生成 RSA加密解密 任意文件的读取和保存操作 各环节必要的数据编码转换 图形操作界面。2.1.2 工程方案选择结合现有的常见开发模式综合分析,有多

18、种实现方案,下面陈述其中几种,并分析选择一种解决方案,并给出工程框架。1.整个工程使用java平台实现RSA密钥生成、RSA加密解密的功能实现十分简单,因为标准库中集成几乎所有功能,不需要从RSA算法出发进行编码。在j2se标准库中,javax.crypto中的Cipher类用于具体的加密和解密,java.security包直接提供了数字签名的相关方法。因为有强大的标准库支持,文件的读取和保存操作、各环节必要的数据编码转换、图形操作界面的实现也很简单(使用java.io java.awt或javax.swing 等包),如果结合一种快速开发的IDE,比如JBuilder,整个软件可以在很短的时

19、间内编码完成。如果不考虑非PC设备和机器效率等问题,java平台几乎是最佳解决方案。但是缺点也很明显,如果想把核心算法和功能应用到非PC设备(例如嵌入式手持设备),则要求设备上有支持前面提及的加密类库的CVM;对于在PC上运行,JVM的数据运算速度要远远落后于本地化代码在PC上的运算速度,本软件需要进行大量运算,这一点不适合由java完成。2.整个工程使用.Net平台实现与使用java平台完全类似,加密等有.Net基础类库的支持,不需要大量编码实现,另外由于Visual Studio的强大便利,这种规模的工程可以十分迅速的完成。缺点是只能在有微软.Net Framework的环境运行,在Win

20、dows操作系统,.Net Framework的机器效率好于java平台,但是相比于本地化的代码,还是十分拖沓的。3.整个工程使用Windows本地化程序实现在不应用Windows或第三方现成组件的情况下,需从RSA算法出发编码实现。其他各功能的设计开发,如文件操作、数据编码转换和图形界面等,可以使用ATL、MFC或Windows API实现。这种工程几乎是为Windows量身订做,执行效率最好。但是对于非PC设备,只能方便的移植到运行Windows嵌入式操作系统的设备,向其他操作系统移植困难,需要重新编写大量代码。通常解决本地化代码的移植问题,都是使用C+标准库,即功能尽量多的由C+标准库完

21、成,这样在移植的时候,只需要重新编写操作系统相关的代码即可。这种开发方式比起前两种,缺点就是设计开发模式陈旧,代码烦琐,不方便维护;流行的.Net上的语言引用各种功能比较麻烦。4.考虑可能的复用,针对具体情况分层开发实现综合考虑复用性、可维护性和执行效率,较妥当的方法是分层设计。核心的RSA算法由C+类库实现,针对用户所在的操作系统封装成本地化组件。其他各功能如文件操作、数据编码转换和图形界面等,由托管代码借助虚拟机平台标准库的功能快速开发实现(本文针对选用.Net上的C#论述,选用java由JNI或其他方式调用本地组件,设计模式上是完全类似的)。这种开发方式,核心功能集中在最底层,在不断的封

22、装中针对具体环境对组件功能不断扩充,任意一个层面的封装都可以被直接应用到其他项目,比如在Web使用以前为某窗体程序写的组件、给嵌入式设备交叉编译算法库等。但是每一层都需要依赖底层的所有组件。图2-2形象的说明了分层设计给复用带来的好处。图2-2 综合考虑复用性、可维护性和执行效率的分层设计选用第四种设计方案,上层使用C#,底层算法使用C+,可以由一个Visual Studio解决方案管理,给调试带来极大的方便。整个工程分四层,实现RSA加密算法的C+核心类库、封装C+核心类库的DLL组件、引用DLL的.Net类、实现文件操作功能的.Net窗体应用程序。2.2节详细介绍各部分的设计与开发。考虑到

23、工作量,本软件加解密数据没有严格遵从RSA标准PKCS #1,而是在满足设计要求的前提下,以一种尽可能简单的方式实现加密和解密。2.2 各部分的设计与开发2.2.1 实现RSA加密算法的C+核心类库1. 大数存储和四则运算根据RSA算法的要求,为了实现大数的各种复杂运算,需要首先实现大数存储和基本四则运算的功能。当今开源的大数运算C+类有很多,多用于数学分析、天文计算等,本文选用了一个流行的大数类型,并针对RSA算法和本项目的具体需要对其进行了扩充和改进。下面简单介绍大数存储和四则运算的实现原理。最先完成的功能是大数的存储,存储功能由flex_unit类提供。和普通的类型一样,每一个大数对应一

24、个flex_unit的实例。类flex_unit中,用一个无符号整数指针unsigned * a指向一块内存空间的首地址,这块内存空间用来存储一个大数,所以可以说,大数是被存储在一个以unsigned为单元的线性组中。在方法void reserve( unsigned x )中通过C+的new来给a开辟空间,当flex_unit的实例中被存入比当前存储的数更大的数时,就会调用reserve来增加存储空间,但是当flex_unit的实例中被存入比当前存储的数更小的数时,存储空间并不会自动紧缩,这是为了在运算的时候提高执行效率。结合指针a,有两个重要的无符号整数来控制存储,unsigned z和u

25、nsigned n,z是被分配空间的单元数,随数字变大不断增大,不会自己紧缩,而n是当前存储的大数所占的单元数,组成一个大数的各unsigned单元的存入和读出由set、get方法完成,变量n是只读的。类型unsigned在32位机是32位的,所以对于flex_unit这个大数类来说,每个大数最大可以达到 个字节长,这已经超过了32位机通常的最大内存容量,所以是足够进行RSA所需要的各种运算的。图2-3形象的说明了大数存储类flex_unit对大数的管理。 *a unsigned类型的指针大数占n个单元开辟了z个单元大的内存内存空间图2-3 flex_unit对大数的管理在flex_unit的

26、存储功能基础上,将其派生,得到vlong_value,在vlong_value中实现四则运算函数,并实现强制转换运算符unsigned,以方便大数类型和普通整数的互相赋值。当大数被强制转换为unsigned时,将取其最低四字节的值。四则运算实现的原理十分简单,都是按最基本的算术原理实现的,四则运算过程的本质就是按一定数制对数字的计算,比如相加,就是低位单元对齐,逐单元相加并进位,减法同理。而乘除法和取余也都是按照竖式运算的原理实现,并进行了必要的优化。虽然实现了四则运算函数,但是若是程序里的运算都要调用函数,显得烦琐而且看起来不美观,所以我们另写一个类vlong,关联(Associate,即使

27、用vlong_value类型的对象或其指针作为成员)vlong_value,在vlong重载运算符。这样,当我们操作vlong大数对象的时候,就可以像使用一个简单类型一样使用各种运算符号了。之所以将vlong_value的指针作为成员而不是直接构造的对象,也是为了提高执行效率,因为大型对象的拷贝要消耗不少机器时间。2. 大数幂模与乘模运算Montgomery幂模算法在实现了vlong类型后,大数的存储和四则运算的功能都完成了。考虑到RSA算法需要进行幂模运算,需要准备实现这些运算的方法。所以写一个vlong的友元,完成幂模运算功能。幂模运算是RSA 算法中比重最大的计算,最直接地决定了RSA

28、算法的性能,针对快速幂模运算这一课题,西方现代数学家提出了很多的解决方案。经查阅相关数学著作,发现通常都是依据乘模的性质,先将幂模运算化简为乘模运算。通常的分解习惯是指数不断的对半分,如果指数是奇数,就先减去一变成偶数,然后再对半分,例如求D=,E=15,可分解为如下6个乘模运算。归纳分析以上方法,对于任意指数E,可采用如图2-4的算法流程计算 。开始D=1;P=C mod nE0?E为奇数?E=E-1E为偶数?E=E/2YesNoResult=D结束YesYesNoNo图2-4 幂模运算分解为乘模运算的一种流程按照上述流程,列举两个简单的幂模运算实例来形象的说明这种方法。求的值开始D = 1

29、P = 2 mod 17 = 2E = 15E奇数D = DP mod n = 2P = PP mod n = 4E = (E-1)/2 =7E奇数D = DP mod n = 8P = PP mod n = 16E = (E-1)/2 =3E奇数D = DP mod n = 9P = PP mod n = 1E = (E-1)/2 =1E奇数D = DP mod n = 9P = PP mod n = 1E = (E-1)/2 =0最终D = 9 即为所求。求的值开始D = 1P = 2 mod 17 = 2E = 8E偶数D = 1P = PP mod n = 4E = E/2 =4E偶数

30、D = 1P = PP mod n = 3E = E/2 =2E偶数D = 1P = PP mod n = 9E = E/2 =1E奇数D = DP mod n = 9P = 不需要计算E = (E-1)/2 =0最终D = 9 即为所求。观察上述算法,发现E根据奇偶除以二或减一除以二实际就是二进制的移位操作,所以要知道需要如何乘模变量,并不需要反复对E 进行除以二或减一除以二的操作,只需要验证E 的二进制各位是0 还是1 就可以了。同样是计算,下面给出从右到左扫描二进制位进行的幂模算法描述,设中间变量D,P,E的二进制各位下标从左到右为u,u-1,u-2,0。Powmod(C,E,n) D=

31、1; P=C mod n; for i=0 to u do if(Ei=1)D=D*P(mod n); P=P*P(mod n); return D;有些文献将上述算法称为平方乘积二进制快速算法,例如参考文献中的基于RSA算法的一种新的加密核设计,其实这种算法本质上和图2-4的流程完全一致,只是把根据指数奇偶分开的减一和除以二合并成对指数二进制各位的判断而已。在本软件的代码中采用直接扫描vlong二进制各位的办法。剩下的问题就是乘模运算了。提高乘模运算的速度是提高模幂运算速度的关键。一般情况下,n是数百位乃至千位以上的二进制整数,用普通的除法求模而进行乘模运算是不能满足速度的要求的。为此,Mo

32、ntgomery在1983年提出了一种模加右移的乘模算法(主要著作发表于1985年),从而避免了通常求模算法中费时的除法步骤。本软件仅仅是应用Montgomery(蒙哥马利)算法,算法的具体推导证明需要颇多数论知识,不在本文的讨论范围内,如需了解可参见蒙哥马利的相关著作。下面简单描述RSA中常用的Montgomery(蒙哥马利)算法供参考理解源程序。选择与模数n互素的基数R=2k,n满足2k1n2k, n应为奇数。并且选择R-1及n,满足0 R-1n, 0 nn,使得 RR-1-nn1。对于0mRn的任意整数,Montgomery给出求模乘法mR-1 mod n 的快速算法M(m):M(m)

33、if (tn) return (t-n); else return t;因为,故t为整数;同时,得。由于,M(m) 中t结果范围是0t=n) x -= n;return x;exp(C,E,n) D=R-n; P=C*R mod n;i=0; while(true) if(E的当前二进制位Ei=1)D=M(D*P); /从低位到高位检测二进制位i+=1;if(i=E的二进制位数)break; P=M(P*P);return D*R-1 (mod n);在具体的实现中,对应monty类的mul和exp方法。全局函数modexp初始化monty对象并调用其exp方法,使用的时候直接调用modexp

34、即可。3. 寻找素数Eratosthenes筛选与Fermat素数测试首先要说明的是,事实上,当今的计算机还不足以聪明到立刻计算生成一个很大的随机素数。一般来说,要得到100%准确的大素数,都是通过查已经计算好的素数表的方式。但是素数表的方式给RSA的安全性带来隐患,因为攻击者如果得到了密钥生成时所使用的素数表,攻破RSA加密的难度将会大大降低。本程序起初使用素数表的方式,后来考虑到安全性问题,生成密钥的方式改为随机计算生成。这样,短时间内如果要得到一个100%准确的大素数是很困难的,只能以尽可能高的概率得到一个大素数。经过2.2.1.1和2.2.1.2小节,所有的大数运算功能都准备完毕,在此

35、基础上,本工程将寻找素数的功能置于类Prime_factory_san之中。外部只要调用本类实例的成员vlong find_prime( vlong & start )就可以以大数start为起点,得到一个数,这个数是素数的概率很大。下面介绍寻找素数的原理。首先在需要寻找素数的整数范围内对整数进行筛选,把所有确知为合数的整数排除出去。程序中构造了一个数组b,大小为一轮素数搜索的范围,记搜索范围大小为SS。b0到bSS分别对应大数start到start+SS。b中所有元素先初始化为1,如果对应的大数确定为合数,就将b中对应的元素置为0。最后,只需对那些b中为1的元素对应的大数进行比较确切的素数测

36、试即可,只要被测试的数是素数概率达到一定门限,就判这个数为素数。这样做既保证了这段程序可以在短时间内执行完,又保证了可以以比较高的准确度得到素数。函数find_prime先把b的所有元素赋值为1,然后按参数start给标记数组b的各元素赋0值。下面描述标记数组b的赋0值算法。首先,在类Prime_factory_san被构造的时候,构造函数中从2开始搜寻一些小素数,记录在数组pl中,共记录NP个。这些小素数用来当作因子,他们的倍数将被从大素数搜索范围内剔除(即把数组b的对应元素标记为0),剔除的程序代码如下。 for (i=0;inp;i+) unsigned p = pli; unsigne

37、d r = start % vlong(p); if (r) r = p - r; while ( r 0 x=r图2-5 在素数搜索范围内剔除小素数因子p的倍数接下来,对可能为素数的数(即标记数组b中值为1的元素对应的数)进行素数测试。数论学家利用费马小定理研究出了多种素数测试方法,本程序使用一种最简单的方式,直接应用费马小定理。取一个与p互素的整数A,对于大素数p来说应该满足Ap-1mod p=1,但是我们把p代入一个大整数,满足这个关系的数不一定是素数。这时我们改变A,进行多次测试,如果多次测试都通过,这个数是素数的概率就比较大。按这种原理,我们编写素数测试函数如下。int is_pro

38、bable_prime_san( const vlong &p ) const rep = 4; /测试次数 const unsigned anyrep = 2,3,5,7 ; /测试用的底数 for ( unsigned i=0; irep; i+=1 )if ( modexp( anyi, p-vlong(1), p ) != vlong(1) ) return 0; /modexp是幂模函数,按上一小节叙述的算法编码。/这里modexp计算anyip-1mod p。 return 1;测试通过,程序就判定这个数为找到的素数,将找到的素数返回给上层程序使用。在这里其实有一个不可忽视的问题,

39、就是得到一个测试通过的合数。对于这种情况,RSA算法加密解密是否还可以实现,是一个需要从数学角度论证的问题。因为得到素数的概率很高,经过一整天的生成密钥和加密操作,没有发现失败的密钥, 所以本文暂没有对这个问题进行讨论。综上所述,总结素数寻找的流程,如图2-6所示。 开始按start参数初始化标记数组bSS ; i=0计数iSS?bi=1?判定为素数?start+=1;i+=1结束返回素数寻找结果startYesYesYesNoNoNo图2-6 函数find_prime寻找素数的流程框图得到了大素数,即RSA算法中的p、q,我们就可以计算出密钥,进行加密等操作了。4. 二元一次不定方程在RSA

40、 算法中,往往要在已知A、M的情况下,求B的最小值,使得 (AB) mod M = 1。即相当于求解B、N都是未知数的二元一次不定方程 AB-MN=1的最小整数解。而针对不定方程ax-by=1 的最小整数解,古今中外都进行过详尽的研究,西方有著名的欧几里德算法,即一种辗转相除法,中国有秦九韶的“大衍求一术”。欧几里德算法是一种递归算法,较容易理解。下面举例说明用欧几里德算法求解二元一次不定方程的最小整数解。给定不定方程11x-49y=1,求最小的x(1) 11 x - 49 y = 1 49 mod 11 = 5(2) 11 x - 5 y = 1 11 mod 5 = 1(3)x - 5 y

41、 = 1 5 mod 1 = 0逆向代入:令y=0 代入(3)得x=1令x=1 代入(2)得y=2令y=2 代入(1)得x=9x=9;y=2即为所求。程序中,全局函数vlong modinv( const vlong &a, const vlong &m )用来完成这种算法。对应前面的叙述,参数a对应A,参数m对应M,函数返回值即为B的最小值。5. 按常规RSA算法实现加密与解密最后,类RSA_san基于前面的准备工作,实现RSA密钥生成和加解密的功能(算法在此不再赘述,RSA算法协议见http:/www.di-.au/rsa_alg.html)。为了方便阅读,整个类的源程序中,所使用的变量字

42、母均和RSA算法协议中一致。在类RSA_san的构造函数里,执行准备一对随机密钥的操作。之后可以直接使用类的其他成员进行RSA加解密操作,也可以载入以前保存的密钥或再次随机生成密钥。类中各成员频繁的用到字符串和vlong类型的转换,因为大数是用字符串置入的,而把大数读出,也是保存在字符指针指向的一段内存空间里,所以也是字符串。所以,需要实现一系列的编码转换函数,比如将unsigned指针指向的一段空间里保存的一个大数,表示成十六进制形式的字符串文本。编码转换通常是用C风格的指针操作和sprintf函数来完成。需要加密和解密的数据也是通过字符串参数置入的。由于字符串的结尾字符“0”实际上也可能是

43、需要加密的数据,所以置入的串长度并不能以“0”来决定,程序里引入一个unsigned类型的参数来决定置入的串长度,这样就解决了加密连0数据时候被截断的问题。因为是对文件加密的软件,需要加密的数据通常并不止几字节,这时由上层程序将数据按用户的设置分块,分别加密或解密。本软件默认的分块大小是1字节,即逐个字节作为参数,调用C+核心模块中的方法。加密解密流程均为标准RSA算法,具体过程和使用方法参见源程序和接口文档。6. 核心类库综述综上几小节所述,实现RSA加密算法的C+核心类库由六个类组成,类名和对应的功能描述总结如表2-1所示。各个类之间的关系如图2-7所示。表2-1 RSA加密算法的C+类库

44、中的类class flex_unit大数运算和存储最基本的类,主要实现超大整数的存储和索引管理。class vlong_value是flex_unit的派生类,在灵活大数存储的基础上实现四则运算函数。class vlong以vlong_value为基础(将一个vlong_value指针作成员),重载运算符。class monty为RSA准备大数求幂模运算的函数,vlong的友元。class Prime_factory_san素数工厂,寻找大素数的类。class RSA_san在前5个类的基础上,实现RSA核心算法的类。图2-7 C+核心功能类图另外需要说明的是,程序中有几个不属于任何类的全局函数,比如应用辗转相除法求最大公约数的函数gcd、解同余方程的函数modin

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 办公文档 > 其他范文


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号