消息摘要是一种确保消息完整性的功能。消息摘要获取消息作为输入并生成位块(通常是几百位长),该位块表示消息的指纹,是一个定长的输出序列。消息中很小的更改(比如说,由闯入者和窃听者造成的更改)将引起指纹发生显著更改。消息摘要函数是单向函数(Hash函数)。从消息生成指纹是很简单的事情,但生成与给定指纹匹配的消息却很难。大多数强函数使用散列法,比较常见的消息摘要算法有MD5和SHA(包括SHA-1、SHA-256、SHA-512等)。
2.2客户端的关键
技术细节与说明(JAVA描述)
(1)声明变量并进行初始化
String ID=""; //用户ID
String UserPass=""; //用户密码,由PIN1和PIN2组合而成
Random rand=new Random();
Date da1=new Date();
String TimeMark=""; //时间戳
String IDInfoMark=""; //消息摘要
byte[] RandStr=new byte[20]; //随机序列
(2)将ID+UserPass+RandStr+TimeMark生成消息摘要,保存在IDInfoMark
rand.nextBytes(RandStr); //将随机数传入随机序列
TimeMark=da1.toString(); //通过Date对象实例产生时间戳
//生成MessageDigest对象,选用SHA-512算法
MessageDigest m=MessageDigest.getInstance("SHA-512");
//将ID和UserPass转化成UTF8类型,并传递给m的update方法
m.update((ID+UserPass).getBytes("UTF8"));
m.update(RandStr); //将RandStr传递给m的update方法
m.update(TimeMark.getBytes("UTF8"));//将TimeMark传递给m的update方法
byte s[]=m.digest();//计算消息摘要
for( int i=0;i<s.length;i++)
{
//得到IDInfoMark
IDInfoMark+=Integer.toHexString((0x000000ff&s[i])|0xffffff00).substring(6);
}
(3)将IDInfoMark、用户ID、随机序列RandStr和时间戳加密后发送给服务器,需要注意的一点是IDInfoMark、用户ID、随机序列RandStr和时间戳之间必须用一定的符号隔开,例如:(IDInfoMark)000000000000(ID)000000000000(RandStr)000000000000(TimeMark),
该部分的相关代码在文献[2]中有专门论述,文献[3]中也有详细的说明。
2.3服务器端的关键
技术细节与说明(JAVA描述)
(1)对客户端传送过来的用户登陆信息密文解密后分离出IDInfoMark、用户ID、随机序列RandStr和时间戳TimeMark,我们在服务器端也要声明相应的变量。
/*由于服务器端可能有多个用户同时登陆,因此变量一般采用数组和向量类型,
为说明方便,我们仍然采用一般变量*/
String ID=""; //用户ID
String password=""; //用户真正密码,从服务器中得到
String TimeMark=""; //时间戳
String IDInfoMark=""; //客户端生成的消息摘要
String PassInfoMark=""; //服务器端生成的消息摘要
String TxtSQL=""; //SQL语句
Boolean FLAG; //登陆是否成功标志
byte[] RandStr=new byte[20];//随机序列
(2)执行SQL操作,获得password的值。
/*在实际应用中,一般我们可以采用三层
网络结构,关于用户的身份验证与数据操作可以单独用一个中间层应用服务来实现,为说明方便起见,我们采用C/S结构*/
String url="jdbc:odbc:fortune"; // fortune是ODBC数据源
Connection con=null;
Statement sm=null;
ResultSet rs=null;
try
{ //加载 JDBC-ODBC bridge驱动程序
Class.forName("com.sun.jdbc.odbc.JdbcOdbcDriver");
}
catch(Exception e)
{
System.out.println("无法装载JDBC-ODBC Brideg驱动程序");
return;
}
//与数据库建立连接
try
{
con=DriverManager.getConnection(url);
sm=con.createStatement(); //创建对象
//执行SQL语句
TxtSQL="SELECT * FROM user_info WHERE user_id=’"+ID+"’";
rs=sm.executeQuery(TxtSQL);
password=rs.getString(2);//获取用户真正密码
}
catch(SQLException e){ }
finally{
try{ //关闭对象
rs.close();
sm.close();
//关闭连接
con.close();}
catch(SQLException e){}
}
(3)将ID+password+RandStr+TimeMark生成消息摘要,保存在PassInfoMark
//生成MessageDigest对象,选用SHA-512算法
MessageDigest m=MessageDigest.getInstance("SHA-512");
//将ID和password转化成UTF8类型,并传递给m的update方法
m.update((ID+password).getBytes("UTF8"));
m.update(RandStr); //将RandStr传递给m的update方法
m.update(TimeMark.getBytes("UTF8"));//将TimeMark传递给m的update方法
byte s[]=m.digest();//计算消息摘要
for( int i=0;i<s.length;i++)
{
//得到PassInfoMark
PassInfoMark+=Integer.toHexString((0x000000ff&s[i])|0xffffff00).substring(6);
}
(4) 比较PassInfoMark和IDInfoMark
if (PassInfoMark.compareTo(IDInfoMark)==0)
FLAG=true;//如果相同,则登陆成功标志为ture
else
FLAG=false; //如果不相同,则登陆成功标志为false
3 总结
我们针对
网络信息系统的口令验证的安全问题,提出一种基于SHA和一次性口令验证
技术的解决方案,在远程实时股票信息管理系统证明了该方案具有很高的安全性和实用性,同时该方案抛开了抽象难懂的密码学和
协议理论,易于被软件开发者掌握并应用。同时,这种方法可以应用其它安全信息工程中去。
参 考 文 献
[1](英)Ross J.Anderson著,蒋佳等译.信息安全工程[M].北京:机械工业出版社,2003
[2](美)Jess Garms著,庞南等译. Java安全性编程指南[M].北京:电子工业出版社 2002
[3] Jianxin Yan, Alan Blackwell, Ross Anderson,Alasdair Grant. The memorability and security ofpasswords . some empirical results.UCAM-CL-TR-500[R].University of Cambridge Computer Laboratory, September 2000
[4](美)Joseph J.Bambara等著,刘堃等译. J2EE
技术内幕[M].北京:机械工业出版社 2002
[5](美)Li Gong著.JAVA 2平台安全
技术——结构、API设计和实现[M].北京: 机械工业出版社 2000
[6](美)John Bell Tony Loton. Java Servlets 2.3编程指南[M].北京: 电子工业出版社 2002
[7] http://www.nsfocus.net
[8] http://www.xfoucus.net
A New Verification Technology Base on SHA and OTP
Abstract: To the password security of the network information system, proposes a new kind of verification scheme base on SHA and OTP, Practice has proved that this scheme has very high security and practicality.
Key words: SHA; OTP; security engineering
Email:fleshwound@sohu.com