加密网络数据

it2022-05-09  36

网络数据加密需要解决三个问题: 完整:数据不被篡改; 安全:数据不被截获,或者截获也无法得到明文; 可靠:数据从真正的发送方而来,其他人无法伪造一个数据来欺骗接受方; 下面例子只解决了安全这个问题:   非对称算法使用的两个密钥有如下关系:使用公共密钥加密的信息只能被相应的私有密钥解密。因此,我首要求你给我发送你的公共密钥。在发送给我的途中可能有人会截取它,但是没有关系,因为他们只能使用该密钥给你的信息加密。我使用你的公共密钥加密文档并发送给你。你使用私有密钥解密该文档,这是唯一可以解密的密钥,并且没有通过网络传递。   不对称算法比对称算法计算的花费多、速度慢。因此我们不希望在线对话中使用不对称算法加密所有信息。相反,我们使用对称算法。下面的例子中我们使用不对称加密来加密对称密钥。接着就使用对称算法加密了。实际上安全接口层(SSL)建立服务器和浏览器之间的安全对话使用的就是这种工作方式。 示例是一个TCP程序,分为服务器端和客户端。服务器端的工作流程是:    从客户端接收公共密钥。    使用公共密钥加密未来使用的对称密钥。    将加密了的对称密钥发送给客户端。    给客户端发送使用该对称密钥加密的信息。   代码如下:

 

namespace  com.billdawson.crypto { public   class  CryptoServer { private   const   int  RSA_KEY_SIZE_BITS  =   1024 ; private   const   int  RSA_KEY_SIZE_BYTES  =   252 ; private   const   int  TDES_KEY_SIZE_BITS  =   192 ; public   static   void  Main( string [] args) { int  port; string  msg; TcpListener listener; TcpClient client; SymmetricAlgorithm symm; RSACryptoServiceProvider rsa; // 获取端口 try { port  =  Int32.Parse(args[ 0 ]); msg  =  args[ 1 ]; } catch { Console.WriteLine(USAGE); return ; } // 建立监听 try { listener  =   new  TcpListener(port); listener.Start(); Console.WriteLine( " Listening on port {0} " ,port); client  =  listener.AcceptTcpClient(); Console.WriteLine( " connection. " ); } catch  (Exception e) { Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); return ; } try {  rsa  =   new  RSACryptoServiceProvider(); rsa.KeySize  =  RSA_KEY_SIZE_BITS; //  获取客户端公共密钥 rsa.ImportParameters(getClientPublicKey(client)); symm  =   new  TripleDESCryptoServiceProvider(); symm.KeySize  =  TDES_KEY_SIZE_BITS; // 使用客户端的公共密钥加密对称密钥并发送给客。 encryptAndSendSymmetricKey(client, rsa, symm); // 使用对称密钥加密信息并发送 encryptAndSendSecretMessage(client, symm, msg); } catch  (Exception e) { Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); } finally { try { client.Close(); listener.Stop(); } catch { // 错误 } Console.WriteLine( " Server exiting " ); } } private   static  RSAParameters getClientPublicKey(TcpClient client) { //  从字节流获取串行化的公共密钥,通过串并转换写入类的实例 byte [] buffer  =   new   byte [RSA_KEY_SIZE_BYTES]; NetworkStream ns  =  client.GetStream(); MemoryStream ms  =   new  MemoryStream(); BinaryFormatter bf  =   new  BinaryFormatter(); RSAParameters result; int  len  =   0 ; int  totalLen  =   0 ; while (totalLen (len  =  ns.Read(buffer, 0 ,buffer.Length)) > 0 ) { totalLen += len; ms.Write(buffer,  0 , len); } ms.Position = 0 ;  result  =  (RSAParameters)bf.Deserialize(ms); ms.Close(); return  result; } private   static   void  encryptAndSendSymmetricKey( TcpClient client, RSACryptoServiceProvider rsa, SymmetricAlgorithm symm) { //  使用客户端的公共密钥加密对称密钥 byte [] symKeyEncrypted; byte [] symIVEncrypted; NetworkStream ns  =  client.GetStream(); symKeyEncrypted  =  rsa.Encrypt(symm.Key,  false ); symIVEncrypted  =  rsa.Encrypt(symm.IV,  false ); ns.Write(symKeyEncrypted,  0 , symKeyEncrypted.Length); ns.Write(symIVEncrypted,  0 , symIVEncrypted.Length);  } private   static   void  encryptAndSendSecretMessage(TcpClient client, SymmetricAlgorithm symm, string  secretMsg) { //  使用对称密钥和初始化矢量加密信息并发送给客户端 byte [] msgAsBytes; NetworkStream ns  =  client.GetStream(); ICryptoTransform transform  = symm.CreateEncryptor(symm.Key,symm.IV); CryptoStream cstream  = new  CryptoStream(ns, transform, CryptoStreamMode.Write); msgAsBytes  =  Encoding.ASCII.GetBytes(secretMsg); cstream.Write(msgAsBytes,  0 , msgAsBytes.Length); cstream.FlushFinalBlock();  }  }           客户端的工作流程是:    建立和发送公共密钥给服务器。    从服务器接收被加密的对称密钥。    解密该对称密钥并将它作为私有的不对称密钥。    接收并使用不对称密钥解密信息。   代码如下:

 

 

namespace  com.billdawson.crypto { public   class  CryptoClient  { private   const   int  RSA_KEY_SIZE_BITS  =   1024 ; private   const   int  RSA_KEY_SIZE_BYTES  =   252 ; private   const   int  TDES_KEY_SIZE_BITS  =   192 ; private   const   int  TDES_KEY_SIZE_BYTES  =   128 ; private   const   int  TDES_IV_SIZE_BYTES  =   128 ; public   static   void  Main( string [] args) { int  port; string  host; TcpClient client; SymmetricAlgorithm symm; RSACryptoServiceProvider rsa; if  (args.Length != 2 ) { Console.WriteLine(USAGE); return ; } try { host  =  args[ 0 ]; port  =  Int32.Parse(args[ 1 ]);  } catch { Console.WriteLine(USAGE); return ; } try   // 连接 { client  =   new  TcpClient(); client.Connect(host,port); } catch (Exception e) { Console.WriteLine(e.Message); Console.Write(e.StackTrace); return ; } try { Console.WriteLine( " Connected. Sending public key. " ); rsa  =   new  RSACryptoServiceProvider(); rsa.KeySize  =  RSA_KEY_SIZE_BITS; sendPublicKey(rsa.ExportParameters( false ),client); symm  =   new  TripleDESCryptoServiceProvider(); symm.KeySize  =  TDES_KEY_SIZE_BITS; MemoryStream ms  =  getRestOfMessage(client); extractSymmetricKeyInfo(rsa, symm, ms); showSecretMessage(symm, ms); } catch (Exception e) { Console.WriteLine(e.Message); Console.Write(e.StackTrace); } finally { try { client.Close(); } catch  {  // 错误 } } } private   static   void  sendPublicKey( RSAParameters key, TcpClient client) { NetworkStream ns  =  client.GetStream(); BinaryFormatter bf  =   new  BinaryFormatter(); bf.Serialize(ns,key); } private   static  MemoryStream getRestOfMessage(TcpClient client) { // 获取加密的对称密钥、初始化矢量、秘密信息。对称密钥用公共RSA密钥 // 加密,秘密信息用对称密钥加密 MemoryStream ms  =   new  MemoryStream();  NetworkStream ns  =  client.GetStream(); byte [] buffer  =   new   byte [ 1024 ]; int  len = 0 ; //  将NetStream 的数据写入内存流 while ((len  =  ns.Read(buffer,  0 , buffer.Length)) > 0 ) { ms.Write(buffer,  0 , len); } ms.Position  =   0 ; return  ms; } private   static   void  extractSymmetricKeyInfo( RSACryptoServiceProvider rsa, SymmetricAlgorithm symm, MemoryStream msOrig)  { MemoryStream ms  =   new  MemoryStream(); //  获取TDES密钥--它被公共RSA密钥加密,使用私有密钥解密 byte [] buffer  =   new   byte [TDES_KEY_SIZE_BYTES]; msOrig.Read(buffer, 0 ,buffer.Length); symm.Key  =  rsa.Decrypt(buffer, false ); //  获取TDES初始化矢量 buffer  =   new   byte [TDES_IV_SIZE_BYTES]; msOrig.Read(buffer,  0 , buffer.Length); symm.IV  =  rsa.Decrypt(buffer, false ); } private   static   void  showSecretMessage( SymmetricAlgorithm symm, MemoryStream msOrig) { // 内存流中的所有数据都被加密了 byte [] buffer  =   new   byte [ 1024 ]; int  len  =  msOrig.Read(buffer, 0 ,buffer.Length); MemoryStream ms  =   new  MemoryStream(); ICryptoTransform transform  = symm.CreateDecryptor(symm.Key,symm.IV); CryptoStream cstream  = new  CryptoStream(ms, transform,  CryptoStreamMode.Write); cstream.Write(buffer,  0 , len); cstream.FlushFinalBlock(); //  内存流现在是解密信息,是字节的形式,将它转换为字符串 ms.Position  =   0 ; len  =  ms.Read(buffer, 0 ,( int ) ms.Length); ms.Close(); string  msg  =  Encoding.ASCII.GetString(buffer, 0 ,len); Console.WriteLine( " The host sent me this secret message: " ); Console.WriteLine(msg);  }  }  }

 

转载于:https://www.cnblogs.com/tuyile006/archive/2007/09/17/896505.html


最新回复(0)