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
