赞
踩
项目说明报告
基于JAVA的两个通用安全模块的设计与实现
本文详细介绍了基于口令的身份认证与文件安全传输两个通用安全模块的设计原理和实现过程,分析了当前口令保存的安全性,提出了运用MD5算法等对口令进行处理,并将处理结果保存在数据库中的方法。同时为了进一步增强认证系统的灵活度,设计了用户注册时的口令模式选择、自主修改用户口令、自主选择口令字符串长度等策略。在本文设计的认证过程中,用户输入认证口令信息,作必要的处理之后,会与数据库里的用户真实信息进行对比来验证用户的合法性,合法用户登录成功后可以访问文件安全传输模块;而文件安全传输模块的设计,是应用SSL协议建立文件安全传输通道,可以保障机密文件内容不被窃听、篡改、伪造。整个系统采用JAVA语言对SSL协议、DES、MD5的支持设计实现的,具有设计简练、认证灵活、安全性能可靠、成本低廉等优点,能很好地解决各类企事业单位的用户身份鉴别和传输文件的机密性问题。
身份认证;消息摘要;DES;SSL;加密;解密
目 录
论文总页数:27页
众所周知,随着计算机的发展与普及,计算机担负着存储、管理信息及资源的任务,集中存放着大量数据资源,而且又为众多用户直接共享,而有些资源涉及到机密性,因此这些资源被用户操作前一般需要用户验证用户名及其口令,获得合法用户的操作权限。如果这些口令被非法用户得到,将会造成企业瘫痪,给国家带来巨大的损失,甚至危及国家安全。因此,对访问系统的用户进行身份认证就显得至关重要,身份认证已经成为了计算机信息安全领域中非常重要的一个分支。身份认证作为安全应用系统的第一道防线,是最重要的安全服务,所有其它的安全服务都依赖于该服务,它的失败可能导致整个系统的失败而使身份认证得以有效执行的前提就是相应口令的妥善保管。目前普遍采用的口令保存技术就是将口令直接以明文方式保存。这种方法的特点是简单、易用并且也具备一定的安全性,但随着计算机应用的复杂化、攻击手段的多样化,这种技术的安全缺陷也越来越明显,已经不再适用于安全性要求较高的应用系统。
不但计算机给人们带来了很多便利,计算机网络技术也日益广泛地应用到各个领域。人们通过Internet 进行各种交流,在网上传输大量的信息,应用层次也在不断地深入,应用领域从传统的、小型业务系统逐渐向大型、关键业务系统扩展,典型的如党政部门信息系统、金融业务系统、企业商务系统等,都涉及到一些敏感数据文件的传输,如军事机密、信用卡号等。 这些被传输的数据往往涉及到企业的机密信息,在网络上传输容易面临着各种各样的安全威胁,如伪造、欺骗、窃听、篡改、抵赖等。如何在传输过程中保障这些敏感数据文件的安全将制约着网络技术在商业、金融、国防等领域的进一步发展,这一问题已成为当今计算机网络技术研究的一个热点。如何解决文件传输中的安全,必须有一整套的技术来保证信息的保密性、完整性,同时也应使信息的发送者能对信息的接收者进行确认,并且保证信息发送给可靠的接收者。
现在很多计算机应用程序使用的认证方法都是最简单的口令形式,类似于windows XP操作系统登录过程中输入用户名/口令的基本认证方式。就是系统事先保存每个用户的二元组信息(用户名,密码)。进入系统时用户先输入用户名和口令,系统根据保存的用户信息与用户输入的信息相比较,从而判断用户身份的合法性。很明显,这种身份认证方法操作十分简单,但同时又最不安全,因为其安全性仅仅基于用户口令的保密性,而用户口令一般较短且容易猜测,不能抵御字典攻击,又由于系统一般将正确的用户口令直接存放在程序、文件或数据库中,一方面需要系统管理员是可信赖的,另一方面,一旦攻击者能够访问口令表,或被黑客窃取到,整个系统的安全性就受到了威胁。而保护在网络中传输的数据采用传统的密码技术(对称密码技术),这在一定程度上解决了文件传输保密性问题,但在进行保密通信前,通信双方必须通过某种安全手段得到密钥,这在某些情况下是非常困难甚至是不可能的。安全套接层协议SSL (Secure Socket Layer) 是用来保障数据安全传输的协议,在Internet 上为通信双方提供可靠连接方式下的防窃听、防篡改、防信息伪造的秘密通信,保障数据的安全传输。目前SSL 已成为业界标准,得到了广泛应用,应用比较灵活。
目前,计算机在金融、商业、政治等部门的应用越来越广,防止非法用户通过身份欺诈访问系统资源,变得日益重视。还有各部门在网络上传输文件时,这些被传输的文件如果涉及到机密信息,很容易遭受各种各样的攻击,保护这些机密信息的安全也成为信息化健康发展所要考虑的重要事情之一。本毕业设计选择两个安全模块的设计与实现主要设计口令部分安全模块实现合法用户验证和口令的安全保存和文件安全传输模块实现文件的安全、秘密、可靠传输到接收端。口令部分安全模块具有合法用户验证模块可以进行用户身份注册,安全生成口令,口令更改,口令长度选择,口令生成个数身选择,身份验证等功能。文件安全传输模块具有基于口令的文件加密解密和文件安全传输等功能。设计中除了综合运用以前所学知识(包括以前所学的一些关于网络、编程、信息安全等知识)的能力,同时也了解当今安全技术及编程的一些新技术;既锻炼了实际动手能力,又引导我进行了一次模拟实际产品的开发,对于以后工作能力的培养具有重要的意义。
本系统的设计重点是实现口令部分安全模块与文件安全传输模块。具体实现口令的生成、口令的保存及文件的安全传输等主要功能,并将口令生成和文件加密的实现方法封装,方便程序调用。本毕业设计首先结合本次毕业设计的相关要求写出需求分析;其次,综合运用以前所学的相关知识(包括JAVA开发语言、计算机网络技术、相关协议、信息安全相关的知识等)以及借鉴现有的口令身份认证和基于SSL协议数据安全传输的技术原理,选择所熟悉的开发工具进行本毕业设计的开发;在设计过程中以需求分析为基础,写出系统开发计划、实现流程及相关问题的实现方法,并将两个安全模块实现的关键技术进行封装,提供接口,方便他人调用;同时,在开发设计与实现中,要保存好相关的设计文挡,为后面毕业论文的写作准备材料;最后,系统开发完毕后,进行调试和测试运行,做好调试和测试运行的相关记录,也为后面的毕业论文的写作准备材料。
用户安全登录模块为用户提供身份验证的入口。用户可以根据自己使用口令的类型选择相应的登录模式登录,用户的登录类型根据口令的处理方法不同分为默认类型和一次性类型。
为了使口令保存的安全性更高,要求用户口令在数据库中不能以明文的方式保存在口令表中。对口令的保存及处理有两种方法,一种是默认处理方法,即口令经处理后以另外一种方式存在口令表中,另一种是一次性口令的处理方法,使口令表中的口每进行一次成功的登录,口令表中的口令信息都进行相应的变化,根据口令的类型调用相应的处理方法来处理口令的。
口令注册模块为用户提供口令注册信息。为了增强口令注册的灵活度,方便用户使用自己的口令,用户可以根据自己的喜好选择注册口令的模式,其中口令注册有两种类型,一种为默认型,一种为一次性口令。用户在一次性口令中可以选择口令的长度、个数等,在一次性口令注册成功后,生成的一系列口令可以生成一个口令文件,为用户查看口令提供了便利。
口令更改模块可以为用户提供口令的更改,尤其是对使用一次性口令的用户,如果他用完了限定的口令,可以不用重新注册,而再次获得有效的一次性口令。用户可以根据口令的类型按要求输入相关的信息更改自己的口令。
客户端文件安全传输模块可以进行文件的选择及上传。用户身份验证成功后可以选择要上传的文件,经相应用户的口令加密后再经SSL协议的安全通信密道传递给服务器使文件在传输过程中进行双重保护。
服务器端文件接收模块可以接收客户端发过来的秘密文件。服务器与客户端建立SSL连接成功后接收客户端发送过来的秘密文件,并将之保存在服务器端选定的目录里。
服务器秘密文件解密模块可以打开秘密文件读取密文中的解密参数并生成相应的解密密钥将密文解密,解密后的明文显示在文本框里,同时将明文保存在系统自定义的目录里,方便接收端对明文进行处理。
本系统是在Windows XP环境下,采用J2SDK1.4开发工具,使用Java语言开发的,并采用SQL Server 2000作为数据提供者。
Java语言是一种很优秀的语言,是目前软件设计中极为壮健的编程语言,只要提供了Java解释器,Java编写的软件在执行码上兼容。Java作为一种程序设计语言,它简单、面向对象、不依赖于机器的结构、具有可移植性、安全性、并且提供了并发的机制,具有很高的性能。其次, Java还提供了丰富的类库涉及加解密、消息摘要等,使程序设计者可以很方便地调用这些方法进行二次开发。另外,在JDBC诞生之后,Java在数据库应用领域获得了成功的应用,大大降低了Java语言操作数据库的复杂程度,可以将重心放在功能实现上。
SQL Server 2000是微软公司开发的一个关系数据库管理系统,以Transact_SQL作为它的数据库查询和编程语言。T-SQL是结构化查询语言SQL的一种,支持ANSI SQL-92标准。它上手容易,由于SQLServer与Windows界面风格完全一致,且有许多"向导(Wizard)"帮助,因此易于安装和学习。而且兼容性良好,由于今天Windows操作系统占领着主导地的位,选择SQLServer一定会在兼容性方面取得一些优势。可以通过ODBC数据库访问技术,用于Java技术制作的页面与数据库之间的连接。
为了方便系统方案的设计与功能的开发,在方案设计前,根据前面的需求分析,将系统的功能划分为口令部分功能模块和文件安全传输部分功能模块,这两个模块又各自细分为各个小模块,各小模块的功能流程图如下:
在登录模块中根据需求分析设计了两种登录系统的口令模式,一个是默认口令模式,一个是一次性口令模式,当用户输入用户名及口令后,系统首先判断用户选的是默认口令类型还是一次性口令类型,如果是默认口令类型,则调用系统的默认口令处理方法将用户输入的口令经处理后,系统与数据库建立连接,连接不成功系统提示出错信息,如果连接成功,系统将口令处理后的结果跟数据库中口令表里的相应口令信息比较,经核对,口令信息一致则该用户可进入文件安全传输模块进行操作,否则提示出错信息,要求用户重新验证口令。登录模块流程图如图1所示。
图1 登录模块流程图 |
口令验证 |
验证失败 |
输入用户名 |
输入口令 |
开始 |
默认口令处理 |
连数据库 |
一次性口令处理 |
默认口令 |
Y |
N |
成功 |
出错信息 |
失败 |
一次性口令令 |
进入系统 |
本次口令写入数据库 |
Y |
验证通过 |
N |
在默认注册模块中,用户输入用户名及口令。系统调用口令处理方法,接着连接数据库,连接成功则将口令信息与数据库里的记录比较,如无重复,则将口令及用户名写入数据库,并提示注册成功,如果写入数据库失败,则报失败提示。默认注册模块流程图如图2。
处理口令 |
输入用户名 |
输入口令 |
输确认口令 |
开始 |
口令一致否否 |
连数据库库 |
写入数据库用户名及口令处理结果 |
出错信息 |
失败 |
成功 |
Y |
N |
图2 默认口令注册流程图 |
一次性口令的注册模块流程图
在一次性口令注册模块中,用户输入用户名、口令长度、口令个数及口令。系统调用口令处理方法,接着连接数据库,连接成功则将口令信息与数据库里的记录比较,如无重复,则将最后生成的一个口令及用户名写入数据库,并显示用户要求的口令个数,失败,则报告失败提示。一次性口令的注册模块流程如图3。
口令是否一致 |
开始 |
N |
输入用户名 |
输入口令 |
输入确认口令 |
输入口令长度 |
输入口令个数 |
写入数据库用户名及口令处理结果之一 |
输出要求的一次性口令 |
与数据库连接 |
处理口令 |
成功 |
失败 |
出错信息 |
图3 一次性口令注册流程图 |
|
成功 |
出错信息 |
N |
口令处理 |
是否一致 |
Y |
输入用户名 |
输入原口令 |
输入新口令 |
输入确认口令 |
开始 |
失败 |
连数据库连 |
口令验证 |
写入新口令 |
成功 |
图4 默认口令更改流程图 |
失败 |
图5 一次性口令更改流程图 |
失败信息 |
成功 |
失败 |
口令处理 |
写入新口令 |
输出用户要求的口令 |
成功 |
连数据库 |
口令验证 |
输入用户名 |
输入原口令 |
输入新口令 |
输入确认口令 |
输入口令长度 |
输入口令个数 |
开始骀 |
Y |
一致否 |
N |
失败 |
在文件传输模块中,用户首先选择一个要发送给服务器的文件。接着系统发送与服务器建立SSL连接的请求,成功后,系统调用文件加密方法给文件加密后,发送出去,发送成功失败都提示相应的消息。文件传输流程图如图6所示。
图6 文件安全传输流程图 |
开始 |
选择传输的文件 |
加密文件 |
失败信息 |
成功 |
成功 |
失败 |
与服务器建立SSL连接 |
成功信息 |
连接成功否 |
发送密文 |
失败 |
在服务器接收文件及处理模块中,服务器响应客户端发来的SSL连接的请求,成功后,服务器选一个目录保存密文,接收完毕后,发送接收成功提示。服务器可以随时解密密文传输流程图如图7。
图7 服务器接收文件及处理流程图 |
失败信息 |
失败 |
成功 |
成功 |
开始 |
与客户端建立SSL连接 |
等待客户端连接请求 |
选择解密文件 |
显示并保存明文 |
出错信息 |
解密 |
选择密文保存目录 |
失败 |
接收密文 |
根据口令部分功能模块流程图,口令模块的方案设计主要涉及到两种方式用于口令的认证及处理。
两种方式用于口令设计:
(1)基于单向函数
基于单向函数的方法是计算机存储口令的单向函数值而不是存储口令,当用户将口令传给计算机时,计算机使用单向函数计算,然后把单向函数的运算结果和它以前存储的单向函数值进行比较。由于计算机不再存储口令表,所以敌手侵入计算机偷取口令的威胁就减少了。
(2)基于SKEY原理
SKEY是进行口令认证方式之一,体现了一次性特性,它的实现过程如下:当用户输入初始口令pass,系统计算pass1=f(pass),pass2=f(pass1),……,pass(n+1)=f(passn)。其中n+1为用户要求生成的口令个数,系统将pass,pass1, pass2,……passn 这些口令给用户保管,而将pass(n+1)存在数据库里该用户的名字后面,当用户第一次登录时,输入用户名和口令passn,系统计算f(passn),并把它和数据库里pass(n+1)比较,如果匹配,就证明该用户身份是真的。然后系统将passn 代替pass(n+1)。用户将passn作废,下次登录时用pass(n-1),以此类推。当用完后重新再获取。
以上这两种处理口令的过程中,消息摘要的生成是利用MD5算法求得。MD (Message Digest)消息摘要算法是一种单向散列函数,是当前最为普遍的哈希算法,MD5是第5个版本。对任意长的输入,MD5算法都将产生一个128位的输出。MD5算法是按512位进行处理的,首先它对输入的数据进行补位,使得数据位长度对512求余的结果是448。具体补位操作:先补一个1,然后补0直至满足上述要求,再用一个64位的数字表示数据的原始长度,这样数据就被填补成长度为512位的倍数。接着对数据依次按每次处理512位,每次进行4轮,每轮16步总共64步的数据变换处理,每次输出的结果为128位,然后把前一次的输出作为下一次数据变换的输入初始值,这样最后输出一个128位的杂凑结果。
根据文件安全传输部分功能模块流程图,文件安全传输的方案设计主要涉及到在文件传输前用DES加密算法给要传输的文件加密得到一个加密后的密文,再将密文通过系统建立SSL协议文件安全传输的安全通道传给密文的接收端。在接收端密文接收成功后,接收端可以根据需要,将密文解密成明文,并自动保存在系统默认目录下。
DES是一个分组加密算法,它将明文以64位为分组对数据加密。64位一组的明文从算法的一端输入,64位的密文从另一端输出。DES是个对称算法:加密和解密用的是同一算法(除密钥编排不同以外)。密钥通常表示为64位的数,但每个第8位都用作奇偶校验,因此密钥真正的长度是56位。整个算法是先经过初始置换IP的处理扰乱数据的原来顺序,然后进行16轮迭代运算,最后经过初始置换IP的逆置换IP-1得出64位的加密结果。整个算法如图8,其中一轮DES如图9所示。
输出 |
输入 |
明文64bit码 |
初始变换IP |
逆初始变换IP-1 |
密文64bit码 |
16轮乘积变换 |
图8 DES算法 |
图9 一轮DES |
SSL协议(Secure Socket Layer,安全套接层协议)是基于对称密钥算法和公钥加密算法的加密传输信道的协议,位于应用层与传输层之间,独立于应用层协议,在SSL协议上可加载任何高层应用协议,应用程序可使用SSL应用接口为各类客户端/服务器产品提供安全传输服务,现已成为保密通信的标准。SSL协议采用RSA, DES等加密技术来实现数据的保密性,采用MD5信息摘要算法等来实现数据的完整性,使用数字证书进行身份认证。
SSL协议是一个中间层协议,在OSI模型中,SSL介于传输层(如TCP/IP)和应用层之间,为应用程序提供了一条安全的网络传输通道,提供TCP/IP通信协议数据加密、版本号、会话密钥、数据压缩方法、数据完整性校验算法、客户端与服务器端身份验证等功能。它的主要目标是在两个通信应用之间提供私有性和可靠性。
SSL协议是一个分层的协议,共有两层组成。处于SSL协议底层的是SSL记录层协议(SSL Record Protocol,它位于可靠的传输层协议(如TCP/IP)之上,用于封装高层协议的数据。高层协议主要包括SSL握手协议(SSL HandshakeProtocol)、改变加密约定协议(Change Cipher Spec Protocol)、报警协议(AlertPT'OtOC01)等。
其中SSL握手协议允许服务方和客户方相互认证,并在应用层协议传送数据之前协商出一个加密算法和会话密钥,是SSL协议的核心。
SSL主要的工作流程包括:网络连接建立;与该连接相关的加密方式和压缩方式选择;双方的身份识别;本次传输密钥的确定;加密的数据传输;网络连接的关闭。
(1)应用程序把应用数据提交给本地的SSL;
(2)发送端的SSL根据需要:
a)使用指定的压缩算法,压缩应用数据;
b)使用散列算法对压缩后的数据计算散列值;
c)把散列值和压缩数据一起用加密算法加密;
(3)密文通过网络传给对方;
(4)接收方的SSL
a)用相同的加密算法对密文解密,得到明文;
b)用相同的散列算法对明文中的应用数据散列;
c)计算得到的散列值与明文中的散列值比较;
(5)如果一致,则明文有效,接收方的SSL把明文解压后得到应用数据上交给应用层。否则就丢弃数据,并向发送方发出警告信息。严重的错误有可能引起再次的协商或连接中断。
在SQL Server 2000数据库系统里利用企业管理器创建一个名为MyDB的数据库,并在这个数据库中设计一个表,表名为Person,这个表用于记录注册用户的用户名、口令信息、一次性口令的有效次数等相关信息,用户每次登录系统都要到此表进行身份验证。表的设计如表1所示:
Atribute | Type |
ID | int |
NAME | nchar |
PASSWORD | nchar |
RAND | nchar |
TIMES | int |
表1 用户相关信息表
表Person的说明:
根据需求分析及方案设计的结果,系统设计与实现的总体结构如图10所示。
两 个 通 用 安 全 模 块 的 设 计 与 实 现 |
口令身份验证模块 |
文件安全传输模块 |
客户端文件选择 Myselectfile.java |
客户端文件加密及发送 ChangeFrame1.java |
服务器密文接收 MySSLServerRule.java |
服务器对密文处理 Myserverfile.java |
用户口令验证并登入 LoginFrame.java |
默认口令注册 RegisterFrame.java |
一次性口令注册 RegisterFrame1.java |
一次性口令修改 ChangeFrame1.java |
默认口令修改 ChangeFrame.java |
口令生成及处理模块 MyProductKey.java |
文件内容加解密处理模块 MyEnc_Dec.java |
保存密/明文处理模块 MysaveEnc_Decfile.java |
图10 总体结构图 |
本系统是使用JDBC-ODBC桥驱动程序连接数据库的,JDBC-ODBC桥接器是用JdbcOdbc.Class和一个用于访问ODBC驱动程序的本地库实现的。首先建立ODBC数据源。ODBC数据源存储了如何与指定的数据建立程序的连接的有关信息。
先在WINDOWS ODBC数据源管理器中,建立一个名为“Person”的数据源的步骤如下:在“控制面板”里的“管理工具”中打开ODBC数据源管理器,选择“系统DSN”标签,单击“添加”按钮,选择数据源的驱动程序为SQL Server,输入数据源名称为“Person”,服务器选“本地”,用“使用网络登录ID的WINDOWS NT验证”,单击“下一步”,在“更改默认的数据库为”单选框,选择数据库为“MyDB”,单击“下一步”接受所有的默认选项。完成后,点“测试数据源”按钮,测试提示成功,则数据源配置成功。接着可以在程序中调用Class.forName方法加载JDBC-ODBC驱动程序,再调用DriverManager.getConnection方法发出连接请求。与数据库连接的部分代码如下:
Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" );
String url="jdbc:odbc:Person";
Connection Insertconnection = DriverManager.getConnection( url);
本系统口令认证模块的默认口令实现的原理是基于单向函数,用MD5算出口令摘要,并保存在数据库里,以后每次登录都先将口令计算出摘要,与数据库里的摘要比较。
一次性口令实现原理及身份验证过程是基于SKEY原理,每次计算的方法是当用户第一次注册时,用MD5计算出口令的消息摘要,并从中截取用户要求的口令长度的字符串,作为一个口令生成,如果用户口要求的口令生成的个数大于1,则将这个生成的口令再用MD5计算出口令的消息摘要,并从中截取用户要求的口令长度的字符串,依此类推,计算出用户要求的个数,并将最后一个生成的口令存于数据库中,当用户用这些口令进行身份验证时就与SKEY的认证过程一样。
在DOS下使用J2SDK提供的keytool工具创建密钥库,密钥库名为mykeystore,添加一个名为mytest的证书,mykeystore密钥库为服务器的密钥库。将mytest证书导出到clienttrust密钥库中。clienttrust密钥库为客户端信任的密钥库。
此模块使用的频率比较多,在用户登录、注册、口令更改功能中都要反复用到,因此将此模块功能封装在接口ProductKey中,方便其它程序的调用。在接口里定义了两个同名的方法DigestKey(String str)和DigestKey(String str,int a,int b),由MyProductKey类具体实现它的方法,其中str表示要进行处理的口令字符串,a表示用户口令的长度, b表示用户输入口令的个数,前一个方法用于默认口令处理返回一个些口令的摘要,后一个方法用于一次性口令处理,返回一系列一次性口令。
DigestKey(String str)是将用户输入的口令生成消息摘要,一次性口令的处理方法DigestKey(String str,int a,int b)是将用户初始输入的口令生成消息摘要,然后截取消息摘要字符串的前三个字符,后三个字符,接着根据用户要求的口令长度a,再从消息摘要字符串中第14位开始截取a-6个字符,将这三次取得的字符串连接一起得到一个一次性口令。然后将这个口令按上面方法再产生一次性口令。依此循环,循环b次最后得到b个口令。最终生成用户要求数量的口令及口令长度。
此模块生成消息摘要的部分代码如下:
MessageDigest m=MessageDigest.getInstance("MD5");
m.update(x.getBytes("UTF8"));
byte s[ ]=m.digest( );
MessageDigest类提供了计算消息摘要的方法,首先生成m的对像,执行update()方法将原始数据传递给该对象,然后执行digest()方法得到消息摘要。
一次性口令处理方法部分代码如下:
public String[] DigestKey(String str,int a,int b){
……
for(int j=0; j<num; j++){
MessageDigest m=MessageDigest.getInstance("MD5");
m.update(x.getBytes("UTF8"));
byte s[ ]=m.digest( );
String result="";
for (int i=0; i<s.length; i++){
result+=Integer.toHexString(s[i]);
}
fir = result.substring(0, 3);
sec = result.substring(29, 32);
tir = result.substring(14, 14+len);
c=fir.concat(sec);
v=c.concat(tir);
p[j]=v;
x=p[j];
}
return p;
}
此代码中num为参数b传递给num的口令个数。fir,sec,tir为三次截取的字符串,再由concat()函数将这三个字符串连接成一个一次性字符串口令,保存在p数组中。再将刚生成的口令字符串传递给x字符串,进行下一个口令的生成。如此循环num次,生成num个口令,最后由数组p返回所有生成的一次性口令。
此模块主要用来完成发送文件的加密和接收密文的解密,加密跟解密是基于口令加密的,即由口令生成密钥。这部分功能在客户端发送文件及服务器端解密文件都要使用,因此将此功能也封装在接口Enc_Dec,在Enc_Dec中定义了加密方法Encrypt(String passw,byte[] rand,byte[] text)和解密方法Decrypt(String passw,byte[] rand,byte[] ctext),它们的第一个参数是口令,第二个参数是随机数,第三个参数是加解密的内容。由类MyEnc_Dec具体实现它的方法,这样方便调用,又简化程序。
此模块中完成加密的部分代码如下:
char[] passwd=password.toCharArray( );
PBEKeySpec pbks=new PBEKeySpec(passwd);
SecretKeyFactory kf=
SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey k=kf.generateSecret(pbks);
Cipher cp=Cipher.getInstance("PBEWithMD5AndDES");
PBEParameterSpec ps=new PBEParameterSpec(salt,1000);
cp.init(Cipher.ENCRYPT_MODE, k, ps);
byte ctext[]=cp.doFinal(buff);
类PBEKeySpec用于保存口令,它的构造器传入的参数是字符数组,所以用了字符串的toCharArray( )方法生成字符数组。SecretKeyFactory类的 generateSecret()方法用于生成密钥。PBEParameterSpec类用于指定基于口令加密的的参数,它的构造器的第一个参数为随机数(盐),第二个参数为进行迭代计算的次数。通过Cipher工厂类的getInstance()方法指定加密算法或解密算法所用的算法名字,init()方法对Cipher对象初始化,它的第一个参数指定密码器准备进行加密还是解密第二个参数则是传入加密或解密所使用的密钥。最后执行doFinal(),完成加密。解密方法类似于加密方法,只是在init()方法对Cipher对象初始化时第一个参数指定密码器准备进行解密操作。
此模块主要用来完成保存密文和明文的。由于加密明文中用到了随机数和口令,要解密这样的密文必须要用相同的随机数和口令,因此密文的前两个字节写入口令占的字节数,接着写入八个字节的随机数,再写入口令,最后将密文写入。当要解密文件时根据密文前面的口令长度即可得到口令跟随机数和密文起始内容。进而调用解密方法解密。将这个模块封装在saveEnc_Decfile接口中,由MysaveEnc_Decfile类具体实现它的方法,有利于简化程序,方便调用。
此模块主要完成用户的口令验证登录,由LoginFrame.java文件里的代码实现,运行后的界面有用户名输入框、密码框、密码类型选择框及“确定”、“取消”、“改口令”、“注册”四个按钮组成,其中单击各按钮进入相应的界面。
在此界面上口令验证的操作流程及程序处理如下:
输入:用户名和密码,选择口令类型。
处理:
输出:登录失败信息。
LoginFrame.java文件中类LoginFrame中的成员函数 logindispose()用于接收并校验登录口令的字符,然后引用包中接口ProductKey,根据其成员变量choiceIndex来判断口令类型,调用相应的接口ProductKey中的方法来处理口令,如果choiceIndex值为0则用默认口令处理方法DigestKey()来处理口令,返回一个处理后的消息摘要字符串数组,并将之到数据库里验证。如果choiceIndex值为1,则调用处理一次性口令的DigestKey()方法,但是设b的值为1,只生成1个口令并将之到数据库里验证。成员变量choiceIndex的值如果是1,则将登录的口令(没经过处理)替换数据库里的口令信息以及更改有效次数。
替换数据库里的口令及有效次数代码如下:
loginupdatequery = "Update Person set PASSWORD ='"+logpass+"',TIMES ="+times+"Where NAME = '"+logname+ "'and PASSWORD='"+insertpass+"'";
这部分主要完成用户的口令注册功能,由RegisterFrame.java文件里的代码实现,运行后的界面有用户名输入框、密码输入框、确认密码输入框及“确定”、“返回”两个按钮组成,其中单击各按钮进入相应的界面。
在此界面上注册默认口令的操作流程及程序处理如下:
输入:用户名、密码、确认密码。
处理:
输出:注册成功或失败信息。
RegisterFrame.java文件中类RegisterFrame中的成员函数RegInfoInput()用于接收并校验注册信息的字符,然后引用包中的接口ProductKey中的成员函数DigestKey()默认口令处理方法来处理口令,生成此口令的一个消息摘要,然后连接数据库,执行插入数据库。
这部分主要完成用户的一次性口令注册功能,由RegisterFrame1.java文件里的代码实现,运行后的界面有用户名输入框、密码输入框、确认密码输入框、口令长度、口令个数及“确定”、“返回”两个按钮,其中单击各按钮进入相应的界面。
在此界面上注册一次性口令的操作流程及程序处理如下:
输入:用户名、密码、确认密码。
处理:
输出:注册成功或失败信息。
RegisterFrame1.java文件中的类RegisterFrame1中的成员函数RegInfoInput()用于接收并校验注册用户输入的注册信息,然后引用包中的接口ProductKey,调用接口中的一次性口令处理方法DigestKey()来处理注册用户输入的初始口令,生成用户要求个数和长度的一系列相关联的口令,然后将最后一个生成的口令执行插入数据库。用类keyDialog向用户显示并保存生成的其它口令。
这部分主要完成默认型口令的更改,由ChangeFrame.java文件里的代码实现,用户需要提供用户名,原口令、新口令、确认口令。系统先确定用户的合法性,如果合法,则进行口令更改处理。实现方法类似于前面的默认口令身份认证和注册。
这部分主要完成一次性类型口令的更改,由ChangeFrame.java文件里的代码实现,用户需要提供用户名,原口令、新口令、确认口令、口令长度、口令个数。原口令是用户在前一次生成的一次性口令中没有失效的口令。系统先确定用户的合法性,如果合法,则进行口令更改处理。实现方法类似于前面的一次性口令身份认证和注册。
这部分主要完文件的选择、文件的加密、与服务器建立连接和秘密文件传输,由Myselectfile.java 和MySSLClientFile.java文件里的代码实现,运行后的界面有文件名框、打开文件选择对话框按钮、确定按钮、返回按纽。其中确定按钮用于发送文件。
在此界面上文件传输的操作流程及处理如下:
输入:文件名。
处理:
输出:文件发送成功或失败信息。
Myselectfile.java文件中的类Myselectfile中的成员函数OpenFile()用于打开文件选择框,SentFile()用于显示文件传输成功失败的信息。而在文件MySSLClientFile.java中类MySSLClientFile通过System类的静态方法setProperty()设置系统参数javax.net.ssl.trustStore,指定客户端信任的证书,通过SSLSocketFactory类型创建Socket对像,并用创建的对象的createSocket()方法和服务器指定的端口建立连接。通过getOutputStream()方法得到输出流,通过该输出流发送的信息将加密后传给服务器程序。由Random类生成随机数,并将口令与随机数一起传递给类MyEnc_Dec实现接口Enc_Dec中的Encrypt()方法用于加密文件内容。
此部分与接收端建立连接及指定密钥库代码如下:
System.setProperty("javax.net.ssl.trustStore", "clienttrust");
SSLSocketFactory ssf=
(SSLSocketFactory)
SSLSocketFactory.getDefault( );
s = ssf.createSocket("127.0.0.1", 5432);
这部分主要完成密文的接收、保存、解密相应的密文、并将解密后的文本显示在文本框中并保存在一个默认的目录中,由MySSLServerRule.java文件和Myserverfile.java文件里的代码实现。运行后的界面有两个文件名框、“打开文件选择对话框”按钮、“保存文件选择对话框”按钮、明文显示文本框。其中接收密文区里的“文件选择对话框”按钮用于保存接收的文件,明文区里的按钮用于打开密文执行解密。
在此界面上密文接收并解密、明文显示、保存明文的操作流程及程序处理如下:
输入:文件名。
处理:
输出:密文保存成功或失败信息。
MySSLServerRule.java文件中类MySSLServerRule中通过System类的静态方法setProperty ()设置两个系统参数。方法中的第一个参数是系统参数的名称,javax.net.ssl.keyStore指定密钥库的名称;第二个参数是为系统参数设置的值,javax.net.ssl.keyStorePassword指定密钥库的密码。通过SSLServerSocketFactory类型的对像创建ServerSocket对像。Accept()方法用等待客户程序连接,ServerSocket的getInputStream( )方法可以得到输入流,通过该输入流读取客户端发送来的信息并自动解密。类MysaveEnc_Decfile实现密文、明文的保存。类MyEnc_Dec实现接口中Enc_Dec的Decrypt()方法用来解密密文。
此部分与发送端建立连接及指定密钥库代码如下:
System.setProperty("javax.net.ssl.keyStore","mykeystore");
System.setProperty("javax.net.ssl.keyStorePassword","wshr.ut");
SSLServerSocketFactory ssf=
(SSLServerSocketFactory)
SSLServerSocketFactory.getDefault( );
ServerSocket ss=ssf.createServerSocket(5432);
经过调试后,整个系统可以正常运行,下面是本系统几个主要功能模块的测试。
在界面中输入用户名和密码,再选口令类型(此测试的口令为一次性类型),所以在类型选择框里选“一次性口令”,选好后,点“确定”按钮。如果输入的口令经一次性类型处理后得到的结果到数据库里验证成功后,则进入图12的文件发送界面。
图11 登录界面
当用户顺利通过身份验证,进入文件发送界面时,点击右边的“浏览”按钮,即可打开文件对话框,选择要发送的文件,则选择文件文本框里出现发送的文件路径跟文件名,然后再点击下面的“发送”按钮,则读入所选的文件内容开始加密并发送,文件发送成功后,系统提示文件发送成功,如图12、图13、图14所示。
图12 文件发送界面
图13 文件选择界面
图14 文件发送成功界面
当用户在登录界面的类型框中选择“一次性口令类型”,再点击“注册”按钮时,则进入“一次性口令”的注册窗口,注册用户按要求依次填入相应的注册信息后,点击“确定”按钮,则开始注册。如果用户注册成功,就出现生成相关口令的对话框,生成的“一次性口令”在此对话框里显示。点击该对话框的“粘贴”按钮,则将生成的“一次性口令”保存在桌面上文件名为key的文本文件里,由用户自己保存。方便“一次性口令”用户登入时可以查看。主要过程如图15、图16所示。
图15 一次性口令注册界面
图16 一次性口令注册成功界面
服务器接收密文的界面运行如下几个主要截图,当客户端没有发送密文过来时,接收密文界面里密文接收框里的“浏览”按钮是不可用的,如图17所示。当客户端有文件发送过来时,则密文接收框里的“浏览”按钮呈可用的状态,要求接收端选择密文的保存路径,在接收端单击密文接收框里的可用“浏览”按钮,即可打开文件保存对话框,选择密文的保存路径,如图18所示,保存路径选好后,路径文本框里显示密文保存的完整路径,然后开始接收并保存密文到指定的路径里,当密文接收并保存成功后,系统会提示文件保存成功的消息,如图19所示。
图17 服务器等待接收界面
图18 接收密文保存界面
图19 密文接收保存成功界面
当点击服务器端密文解密框里的“浏览”按钮时,打开文件对话框,在打开的文件对话框里选择需要解密的密文。选好后,密文解密文本框里显示所选的解密文件的完整路径和密文文件名,密文开始解密,并将解密后的明文显示在明文文本框里,同时还自动将明文保存在系统默认的目录,即c盘的SSLfile文件夹里。如图20所示。
图20 密文解密并显示界面
本论文主要描述了基于JAVA的两个通用安全模块的设计与实现,这两个通用安全模块是指口令部分安全模块的设计与文件安全传输部分安全模块的设计。详细的给出了口令保管及认证过程的设计与文件安全传输模块的设计。
口令保存及认证这部分主要是防止非法用户通过身份欺诈访问系统资源,保证合法用户的利益。本文对口令保管及认证的设计是基于文献[2]提出的理论。在该模块中主要设计并实现了两种口令模式,即默认口令模式和一次性口令模式。默认口令模式是基于单向函数。一次性口令模式是基于SKEY原理。文件安全传输模块的设计主要是防止文件在网络上传输时被窃取、篡改等。对这部分的设计主要实现了两个方面的工作,一个是在文件传输前利用登录用户的口令对文件进行加密,然后与接收端建立SSL协议的安全传输通道,由安全通道将文件传输给服务器,这样文件在网络上传输是经过二次加密的。增加了文件传输的安全性。当文件传输成功后,在接收端可以进行相应的解密。
通过努力实现了基于JAVA的两个通用安全模块的设计并通过调试测试成功。
本设计也有一些不足,由于时间和个人能力的有限,在课题的设计研究过程中还留有一些问题有待以后进一步研究。如在文件传输之前用于文件解密的密钥参数保存在密文中,这就存在密钥安全的问题。还有文件在接收端解密成明文后,自动保存在系统目录中,没有根据需要保存明文文件。在今后的学习研究中,应该考滤用某种方式来弥补这些缺陷。
[1] 徐迎晓.JAVA安全性编程实例[M].北京:清华大学出版社,2003。
[2] 曹天杰,张永平,苏成.计算机系统安全[M].北京:高等教育出版社,2003。
[3] 陆正武,蒋武,刘军,石正贵.JAVA项目开发实践[M].北京:中国铁道出版社,2004。
[4] 张曜,张青,郭立山.JAVA程序设计教程[M].北京:冶金工业出版社,2002。
[5] 赖溪松,韩亮,张真诚.计算机密码学及其应用[M].北京:国防工业出版社,2001。
[6] 汪晓平,俞俊,李功.精通Java网络编程[M].北京:清华大学出版社,2005。
[7] 张晓东.Java数据库高级教程[M].北京:清华大学出版社,2004。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。