c#发展

注册

 

发新话题 回复该主题

第四篇c教程socket数据流的加密 [复制链接]

1#
吃铜治白癜风吗 http://baidianfeng.39.net/a_wh/131029/4281177.html
吃铜治白癜风吗 http://baidianfeng.39.net/a_wh/131029/4281177.html

第四篇c#教程socket数据流的加密

接,的socket服务端程序:

namespaceConsoleApplicationSocket01

{

classProgram

{

staticvoidMain(string[]args)

{

Byte[]BytesOfReceived=newByte[];

SocketUnitySocketServer=newSocket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);

IPAddressHostIpAddress=IPAddress.Parse(".0.0.1");

UnitySocketServer.Bind(newIPEndPoint(HostIpAddress,));

while(true){

if(UnitySocketServer.Receive(BytesOfReceived)0)

{

Console.Write(Encoding.UTF8.GetString(BytesOfReceived));

}

stringFrontString=Encoding.UTF8.GetString(BytesOfReceived);

FrontString=FrontString.Substring(0,4);

if(FrontString=="quit")

{

return;

}

}

}

}

}

客户端程序:

namespaceConsoleApplication02

{

classProgram

{

staticvoidMain(string[]args)

{

stringSendedString="HelloWorld!";

SocketUnitySocketSend=newSocket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);

IPAddressHostIpAddress=IPAddress.Parse(".0.0.1");

UnitySocketSend.Bind(newIPEndPoint(HostIpAddress,));

while(true)

{

SendedString=Console.ReadLine();

UnitySocketSend.SendTo(Encoding.UTF8.GetBytes(SendedString),newIPEndPoint(HostIpAddress,));

}

}

}

}

接下来实现对socket数据流的加密。.net类库提供对数据流加密和解密的类,主要的命名空间有System.Security.Cryptography,主要的类有System.Security.Cryptography.CryptoStream,CryptoStream类接受一个普通流,然后对其加密,并返回一个流。

一、先添加命名空间:

UsingSystem.Security.Cryptography;

然后再程序中添加CryptoStream变量。由于每次收发都需要加密,CryptoStream变量应添加在发送函数之前:

usingSystem.Security.Cryptography;

namespaceConsoleApplication02

{

classProgram

{

staticvoidMain(string[]args)

{

stringSendedString="HelloWorld!";

SocketUnitySocketSend=newSocket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);

IPAddressHostIpAddress=IPAddress.Parse(".0.0.1");

UnitySocketSend.Bind(newIPEndPoint(HostIpAddress,));

while(true)

{

SendedString=Console.ReadLine();

CryptoStreamCStream=newCryptoStream();

UnitySocketSend.SendTo(Encoding.UTF8.GetBytes(SendedString),newIPEndPoint(HostIpAddress,));

}

}

}

}

上面的代码存在问题,需要修正。

二、CryptoStream的构造函数接收三个参数,第一个参数是普通的流,第二个参数是加密的算法,第三个参数是CryptoStream流的读写模式。并且在CryptoStream流上的写会直接写入普通的流。

流并不是底层概念,它是上层概念,很多开发软件包都将对计算机的底层资源的操作进行了抽象和统一,把对磁盘、文档、内存的读写操作统一为流,对文档有文档流FileStream,对内存有内存流MemoryStream。

先添加命名空间System.IO,它包含有流的诸多类:

usingSystem.IO;

然后构造一个空的MemoryStream,使用MemoryStream()构造函数初始化的空流具有可读、可写、可变大小的特性:

namespaceConsoleApplication02

{

classProgram

{

staticvoidMain(string[]args)

{

stringSendedString="HelloWorld!";

SocketUnitySocketSend=newSocket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);

IPAddressHostIpAddress=IPAddress.Parse(".0.0.1");

UnitySocketSend.Bind(newIPEndPoint(HostIpAddress,));

while(true)

{

SendedString=Console.ReadLine();

MemoryStreamStreamSendString=newMemoryStream();

CryptoStreamCStream=newCryptoStream();

UnitySocketSend.SendTo(SendedString,newIPEndPoint(HostIpAddress,));

}

}

}

}

三、继续修正,添加加密算法Rijndael,并初始化加密流CryptoStream:

在CryptoStream的构造函数中要传入MemoryStream流和加密算法

namespaceConsoleApplication02

{

classProgram

{

staticvoidMain(string[]args)

{

stringSendedString="HelloWorld!";

SocketUnitySocketSend=newSocket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);

IPAddressHostIpAddress=IPAddress.Parse(".0.0.1");

UnitySocketSend.Bind(newIPEndPoint(HostIpAddress,));

while(true)

{

SendedString=Console.ReadLine();

MemoryStreamStreamSendString=newMemoryStream();

RijndaelRijndaelAlg=Rijndael.Create();

CryptoStreamCStream=newCryptoStream(StreamSendString,RijndaelAlg.CreateEncryptor(RijndaelAlg.Key,RijndaelAlg.IV),CryptoStreamMode.Write);

UnitySocketSend.SendTo(SendedString,newIPEndPoint(HostIpAddress,));

}

}

}

}

此处RijndaelAlg.Key和RijndaelAlg.IV既是密钥,由于Rijndael是对称算法,解密也是用它们做密钥。

四、将要发送的消息写入加密流:

namespaceConsoleApplication02

{

classProgram

{

staticvoidMain(string[]args)

{

stringSendedString="HelloWorld!";

SocketUnitySocketSend=newSocket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);

IPAddressHostIpAddress=IPAddress.Parse(".0.0.1");

UnitySocketSend.Bind(newIPEndPoint(HostIpAddress,));

while(true)

{

SendedString=Console.ReadLine();

MemoryStreamStreamSendString=newMemoryStream();

RijndaelRijndaelAlg=Rijndael.Create();

CryptoStreamCStream=newCryptoStream(StreamSendString,RijndaelAlg.CreateEncryptor(RijndaelAlg.Key,RijndaelAlg.IV),CryptoStreamMode.Write);

CStream.Write(Encoding.UTF8.GetBytes(SendedString),0,Encoding.UTF8.GetBytes(SendedString).Length);

CStream.Flush();

CStream.Close();

UnitySocketSend.SendTo(SendedString,newIPEndPoint(HostIpAddress,));

}

}

}

}

五、使用流的ToArray()函数提取流的信息,然后发送出去:

namespaceConsoleApplication02

{

classProgram

{

staticvoidMain(string[]args)

{

stringSendedString="HelloWorld!";

SocketUnitySocketSend=newSocket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);

IPAddressHostIpAddress=IPAddress.Parse(".0.0.1");

UnitySocketSend.Bind(newIPEndPoint(HostIpAddress,));

while(true)

{

SendedString=Console.ReadLine();

MemoryStreamStreamSendString=newMemoryStream();

RijndaelRijndaelAlg=Rijndael.Create();

CryptoStreamCStream=newCryptoStream(StreamSendString,RijndaelAlg.CreateEncryptor(RijndaelAlg.Key,RijndaelAlg.IV),CryptoStreamMode.Write);

CStream.Write(Encoding.UTF8.GetBytes(SendedString),0,Encoding.UTF8.GetBytes(SendedString).Length);

CStream.Flush();

CStream.Close();

Byte[]SendedString01=StreamSendString.ToArray();

StreamSendString.Close();

UnitySocketSend.SendTo(SendedString01,newIPEndPoint(HostIpAddress,));

}

}

}

}

六、按Ctrl+F5测试,能够很好的加密。加密了就要能解密,Rijndael算法是对称加密算法,加密和解密使用同一个密钥,Rijndael算法的Key属性返回Byte类型数据。

分享 转发
TOP
发新话题 回复该主题