基于RSA 算法动态相互身份认证的设计(增强版)

  参考论文:基于RSA 算法动态相互身份认证的设计

  首次看到这篇论文对RSA算法及原理还不熟悉,读着很吃力,连着读了几十遍,就是不理解作者的思路方案,接着对RSA的算法进行了一番演练后对论文的思路渐渐明了.先贴上论文中描述的设计思想:

  假设需要认证双方为A 和B ,A 和B 在通信前需要进行身份认证,以下是本文设计的身份认证思想.
  (1) A 将自己的身份IDA 传递给B ,但是B 不能确定此信息是来自A 还是窃密者C.
  (2)B 收到IDA 后,产生一个随机的消息RB ,用A 的公钥PA 加密IDA 和RB 得到y1 = EPA ( IDA +RB ) , 并用自己的私钥SB 做y2 = DSB ( EPA ( IDA + RB ) ) 运算即签名, 将结果EPA ( IDA + RB ) 和DSB ( EPA ( IDA + RB ) ) 传送给A.
  (3) A 收到消息后用B 的公钥PB 对DSB ( EPA ( IDA + RB ) ) 进行验证,验证原理是根据EPB (DSB ( EPA ( RB ) )= EPA ( RB ) . 由于只有合法的B才拥有公钥SB ,因此可以通过将计算结果与EPA ( RB ) 比较,A就可以确认通信对方是否是B. 如果验证通过,A 就可以确认通信对方的确是B ,并且对EPA ( IDA + RB ) 进行解密,解密的原理
是DSA ( EPA ( IDA + RB ) ) = IDA + RB . 通过解密得到IDA + RB ,分离IDA 和RB .
  (4) A 将求得的RB 用B 的公钥PB 加密传送给B ,因为只有合法的A 可以求得RB 从而可以得到正确的EPB ( RB ) ;B 只需用自己的私钥SB 解密( EPB ( RB ) ) 即可得到DSB ( EPB ( RB ) ) = RB ,将此RB 与原来的RB对比就可以确认对方是否是A.

  流程图如下:

 

  后来根据自己的需要多加了两步认证,本人任务这样会更复杂,难以破解.

  B向A发送RB的签名,A收到签名后比较第二步中RB进行判断,然后把版权信息与RB混合后利用B的公钥加密并发送给B,B利用自己的私钥解密并分解,以此B来判断A的版权信息返回升级指示.

  服务端部分核心:

服务端
1 string[] msgs = m.Split(new char[] {':'});
2 //数据包类型
3 //step1:启动验证第一步;
4 //step2:启动验证第二步;
5 //step3:启动验证第三步;
6   string type = msgs[0];
7 //数据包数据
8   string data = msgs[1];
9 switch (type)
10 {
11 case "step1":
12 {
13 Console.WriteLine("启动验证第一步;");
14 string IDA = data;
15
16 string AB = IDA + "," + RB;
17 //用A 的公钥PA 加密IDA 和RB 得到y1 = EPA ( IDA +RB )
18 string y1 = RSA.RSAEncrypt(RSA.ReadPublicKey("public.xml"), AB);
19 //用自己的私钥SB 做y2 = DSB ( EPA ( IDA + RB ) ) 运算即签名
20 string y2 = RSA.SignatureFormatter(RSA.ReadPrivateKey("private.xml"), RSA.GetHash(y1));
21
22 string send = "step1:" + y1 + "," + y2;
23 sForm.setText(send);
24 //加密传输
25 send = sm.Encrypto(send);
26
27 byte[] temp = Encoding.UTF8.GetBytes(send);
28 streamToClient.Write(temp, 0, temp.Length);
29 streamToClient.Flush();
30 Console.WriteLine("Sent: {0}", send);
31 break;
32 }
33 case "step2":
34 {
35 Console.WriteLine("启动验证第二步;");
36 string DAB = RSA.RSADecrypt(RSA.ReadPrivateKey("private.xml"), data);//解密RB
37
38 if (DAB == RB)
39 {
40 RB = RSA.GetHash(RB);
41 string send = "step2:" + RB;
42 sForm.setText(send);
43 //加密传输
44 send = sm.Encrypto(send);
45
46 byte[] temp = Encoding.UTF8.GetBytes(send);
47 streamToClient.Write(temp, 0, temp.Length);
48 streamToClient.Flush();
49 Console.WriteLine("Sent: {0}", send);
50 }
51 else
52 sForm.setText("RB出错了...");
53 break;
54 }
55 case "step3":
56 {
57 Console.WriteLine("启动验证第三步;");
58 data = RSA.RSADecrypt(RSA.ReadPrivateKey("private.xml"), data);
59 msgs = data.Split(new char[] {','});
60 string ver = msgs[0];
61 string DRB = msgs[1];
62 if (RSA.GetHash(DRB) == RB)
63 {
64 sForm.setText(ver);
65 }
66
67 break;
68 }
69 }
70

 

 

  客户端部分核心:

客户端
1 try
2 {
3 lock (streamToServer)
4 {
5 bytesRead = streamToServer.EndRead(ar);
6 }
7 if (bytesRead == 0) throw new Exception("读取到0字节");
8
9 string rMsg = Encoding.UTF8.GetString(buffer, 0, bytesRead);
10 rMsg = sm.Decrypto(rMsg);
11
12 Console.WriteLine("Received: {0}", rMsg);
13 string[] msgs = rMsg.Split(new char[] { ':' });
14 //数据包类型
15 //step1:启动验证第一步;
16 //step2:启动验证第二步;
17 //step3:启动验证第三步;
18   string type = msgs[0];
19 //数据包数据
20 string data = msgs[1];
21
22
23
24 switch (type)
25 {
26 case "step1":
27 {
28 Console.WriteLine("启动验证第一步;");
29 string[] datas = data.Split(new char[] {','});
30 string y1 = datas[0];//EPA ( IDA + RB )
31 string y2 = datas[1];//DSB ( EPA ( IDA + RB ) )
32
33 if (RSA.SignatureDeformatter(RSA.ReadPublicKey("public.xml"), RSA.GetHash(y1), y2))
34 {
35 string AB = RSA.RSADecrypt(RSA.ReadPrivateKey("private.xml"), y1);
36 datas = AB.Split(new char[] { ',' });
37 string IDA = datas[0];
38 RB = datas[1];
39 if (msg.Contains(IDA))
40 {
41 string EAB = RSA.RSAEncrypt(RSA.ReadPublicKey("public.xml"), RB);
42 SendMessage("step2:" + EAB);
43 }
44 else
45 cForm.setText("IDA出错啦...");
46 //cForm.setText(AB);
47 }
48 else
49 cForm.setText("签名出错啦...");
50 break;
51 }
52 case "step2":
53 {
54 Console.WriteLine("启动验证第二步;");
55 if (data == RSA.GetHash(RB))
56 {
57 string send = "Ver" + System.Windows.Forms.Application.ProductVersion + "," + RB;
58 send = "step3:" + RSA.RSAEncrypt(RSA.ReadPublicKey("public.xml"), send);
59
60 SendMessage(send);
61
62 }
63 else
64 cForm.setText("认证不通过...");
65 break;
66 }
67 }
68
69 Array.Clear(buffer, 0, buffer.Length); // 清空缓存,避免脏读
70
71 lock (streamToServer)
72 {
73 AsyncCallback callBack = new AsyncCallback(ReadComplete);
74 streamToServer.BeginRead(buffer, 0, BufferSize, callBack, null);
75 }
76 }
77 catch (Exception ex)
78 {
79 if (streamToServer != null)
80 streamToServer.Dispose();
81 client.Close();
82
83 Console.WriteLine(ex.Message);
84 }

 

posted @ 2010-06-08 20:35  小 段  阅读(919)  评论(0编辑  收藏  举报