UsbKey开发
最近在做UsbKey的开发,所以进行来进行一个总结,希望能对大家有所帮助。
我开发的是飞天的ePass1000ND,对key的验证并未涉及证书,而是利用MD5算法来实现。
UsbKey的验证机制:
当利用密钥进行身份验证时,客户机首先向服务器发送登陆请求。服务器则通过用户名从数据库中取出相应用户的密钥(A)。当服务器收到客户登陆请求后,便向客户机发送一个随机字符串(B),该字符串最终送入客户机的usbkey中用于计算。与此同时,服务器则根据用户名取出对应的密钥并利用发送给客户机的随机字符串(即key的密钥+随机字符串),在服务器上用加密引擎进行运算,得到运算结果(C)。客户机将此随机字符串(B)传入usbkey,usbkey则利用随机字符串(B)与内置在其中的密钥文件(a)通过硬件加密引擎进行运算,也得到一个运算结果(c),客户机再将此结果(c)直接在网络中发送给服务器。服务器比较两个运算结果C和c是否相同便可确定用户的合法性。密钥是存在于usbkey中,并且整个运算过程也是在usbkey中完成的。
在UsbKey中的到随机数的函数HashToken()是基于验证PIN码的,也就是说只有在验证PIN码正确后,这个函数才能进行调用。发现这一点的原因是我们的客户希望能尽量简便的去使用key,客户希望插上key后就能登陆系统。安全性当然是不高的,但这是客户的要求,所以风险自然由他们承担。我的实现方法就是插入key后点击登陆按钮即可。
下面是我开发的代码,用的全是C#(不容易啊,飞天给的例子基本都是vbscript的),我把常用的几个key的函数都封装起来了,在使用的时候调用即可
1using System;
2using System.Data;
3using System.Configuration;
4using System.Data.OracleClient;
5using FT_ND_FULLLib; //添加UsbKey类库的引用
6
7namespace Web.Public
8{
9 /// <summary>
10 /// BS_UsbKey 的摘要说明。
11 /// </summary>
12 public class BS_UsbKey
13 {
14
15
16 public bool UsbKeyPIN_IsCorrect(string strInputPIN)//验证用户输入的PIN码是否正确
17 {
18 //示例化一个key对象
19 ePsM8FullClass ePass;
20
21 ePass = new ePsM8FullClass();
22
23 //读取key的版本号
24 ePass.GetLibVersion();
25
26 try
27 {
28 ePass.OpenDevice(1,"");//打开设备,对key的所以操作都是基于这个函数的
29
30 ePass.VerifyPIN(0,strInputPIN);//验证PIN码的函数
31 }
32 catch
33 {
34 ePass.CloseDevice();//关闭设备
35 return false;
36 }
37
38 ePass.CloseDevice();
39
40 return true;
41 }
42
43 public string GetRandom()//生成用于验证的随机数
44 {
45 string strRandData;
46 Random randomGenerator;
47
48 randomGenerator = new Random(DateTime.Now.Millisecond);
49 strRandData = "";
50
51 for(int i=0; i<19; i++)
52 {
53 strRandData += Convert.ToChar(randomGenerator.Next(97,122));
54 }
55
56 return strRandData;
57 }
58
59 public string GetClientDigest(string strRandData)
60 {
61 string strClientDigest;
62 ePsM8FullClass ePass;
63
64 ePass = new ePsM8FullClass();
65 strClientDigest = "";
66
67 ePass.GetLibVersion();
68
69 try
70 {
71 ePass.OpenDevice(1,"");
72
73 ePass.ChangeDir (0x0300,0,"ASP_DEMO");//改变目录
74
75 ePass.OpenFile(0,1);//打开key里的文件夹
76
77 strClientDigest += ePass.HashToken(1,2,strRandData).ToString();//key进行加密的函数
78 }
79 catch
80 {
81 ePass.CloseDevice();
82 return strClientDigest;
83 }
84
85 ePass.CloseDevice();
86
87 return strClientDigest;
88 }
89 }
90}
91
92
2using System.Data;
3using System.Configuration;
4using System.Data.OracleClient;
5using FT_ND_FULLLib; //添加UsbKey类库的引用
6
7namespace Web.Public
8{
9 /// <summary>
10 /// BS_UsbKey 的摘要说明。
11 /// </summary>
12 public class BS_UsbKey
13 {
14
15
16 public bool UsbKeyPIN_IsCorrect(string strInputPIN)//验证用户输入的PIN码是否正确
17 {
18 //示例化一个key对象
19 ePsM8FullClass ePass;
20
21 ePass = new ePsM8FullClass();
22
23 //读取key的版本号
24 ePass.GetLibVersion();
25
26 try
27 {
28 ePass.OpenDevice(1,"");//打开设备,对key的所以操作都是基于这个函数的
29
30 ePass.VerifyPIN(0,strInputPIN);//验证PIN码的函数
31 }
32 catch
33 {
34 ePass.CloseDevice();//关闭设备
35 return false;
36 }
37
38 ePass.CloseDevice();
39
40 return true;
41 }
42
43 public string GetRandom()//生成用于验证的随机数
44 {
45 string strRandData;
46 Random randomGenerator;
47
48 randomGenerator = new Random(DateTime.Now.Millisecond);
49 strRandData = "";
50
51 for(int i=0; i<19; i++)
52 {
53 strRandData += Convert.ToChar(randomGenerator.Next(97,122));
54 }
55
56 return strRandData;
57 }
58
59 public string GetClientDigest(string strRandData)
60 {
61 string strClientDigest;
62 ePsM8FullClass ePass;
63
64 ePass = new ePsM8FullClass();
65 strClientDigest = "";
66
67 ePass.GetLibVersion();
68
69 try
70 {
71 ePass.OpenDevice(1,"");
72
73 ePass.ChangeDir (0x0300,0,"ASP_DEMO");//改变目录
74
75 ePass.OpenFile(0,1);//打开key里的文件夹
76
77 strClientDigest += ePass.HashToken(1,2,strRandData).ToString();//key进行加密的函数
78 }
79 catch
80 {
81 ePass.CloseDevice();
82 return strClientDigest;
83 }
84
85 ePass.CloseDevice();
86
87 return strClientDigest;
88 }
89 }
90}
91
92
下面是登陆按钮中的调用
1private void btnLogin_Click(object sender, System.Web.UI.ImageClickEventArgs e)
2{
3 BS_UsbKey bsUsbKey = new BS_UsbKey();
4
5 if(bsUsbKey.UsbKeyPIN_IsCorrect(PIN) == false)//验证PIN码
6 {
7 Response.Write("<script>window.alert('PIN码错误')</script>");
8
9 }
10
11 strRandData = bsUsbKey.GetRandom();
12 strClientDigest = bsUsbKey.GetClientDigest(strRandData);
13
14 if(!Object.Equals(strServerDigest,strClientDigest))//验证key的合法性
15 {
16 Response.Write("<script>window.alert('验证通过')</script>");
17 }
18}
2{
3 BS_UsbKey bsUsbKey = new BS_UsbKey();
4
5 if(bsUsbKey.UsbKeyPIN_IsCorrect(PIN) == false)//验证PIN码
6 {
7 Response.Write("<script>window.alert('PIN码错误')</script>");
8
9 }
10
11 strRandData = bsUsbKey.GetRandom();
12 strClientDigest = bsUsbKey.GetClientDigest(strRandData);
13
14 if(!Object.Equals(strServerDigest,strClientDigest))//验证key的合法性
15 {
16 Response.Write("<script>window.alert('验证通过')</script>");
17 }
18}