参考论文:
首次看到这篇论文对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 }