C#实现网络传输数据加密

1. 分组密码

分组密码是将明文消息编码表示后数字序列划分成长为n的分组,各组分别在密钥的作用下进行变换输出等长的数字序列,即密文。一次加密一个数据组,加解密所使用的是同一密钥,故其通常也称为对称加密。分组长n各种不同的对称加密算法取值不同(DES和TripleDES为64位,AES默认为128位,也可以为192位和256位),在对明文消息进行分组时如果最后个分组小于n,则要进行数据填充,使分组长达到n才能进行后续的加密处理。.net平台提供的加密类都很好的处理了上述问题,所以在用C#语言进行实际编码能很简便的完成加解密操作。

Rijndael算法作为AES的一种,已经取代TripleDES(三重DES)成为新的数据加密标准。其分组长度及密钥长度都可变,且比DES算法都要长,使其也具有了更高的安全性。本文的示例程序采用的就是Rijndael算法。

2. 运行模式

分组密码在加密时,明文分组的长度是固定,而实用中待加密消息的数据量是不定的,相邻的两个分组加解密时是否相关,就产生了不同的运行模式。下面主要介绍两种常用的分组密码运行模式

1. ECB模式

ECB模式是最简单的运行模式,各个分组使用相同的密钥进行加密,如图1所示。

 
图1. ECB模式示意图

当密钥取定时,对明文的每一个分组,都有一个唯一的密文与之对应。这也造就了ECB模式的最大特性,同一明文分组在消息中重复出现的话,产生的密文分组也相同。故ECB用于长消息时可能不够安全,如果消息有固定结构,攻击者可能找出这种关系。但因为在ECB模式中,各分组加解密相互独立,所以很方便进行并行计算,提高大型数据加解密的运行效率。

2. CBC模式

为了解决ECB模式的安全缺陷,可以让重复的明文分组产生不同的密文分组,CBC模式就可满足这一要求。如图2所示,在CBC模式中,一次对一个明文分组加密,每次加密使用同一密钥,加密算法的输入是当前明文分组和前一次密文分组的异或,因此加密算法的输入不会显示出于这次的明文之间的固定关系,所以重复的明文分组不会在密文中暴露出这种重复关系。

 
图2 CBC模式示意图

在产生第一个密文分组时,需要有一个IV与第一个明文分组异或。解密时,IV和解密算法对第一个密文分组的输出进行异或以恢复第一个明文分组。IV和密钥一样对于收发双方都是已知的,为了使安全性最高,IV应像密钥一样被保护。

在.NET平台提供的分组加密类默认使用的是CBC模式,但是可以根据需要更改此默认设置。

3. 数据加解密

在实现数据加解密主要涉及到System.Security.Cryptography下的RijndaelManagedCryptoStream类。前面提到.NET平台的分组加密类默认使用的是CBC模式,所以首先要生成密钥Key和IV。在生成RijndaelManaged实例时默认会生成一组长度为16字节随机的Key和IV,在本示例中为了省去通信双方的密钥交换过程,直接指定了Key和IV,加解密都相同。具体看代码,看注释。

数据加密

 1 //创建RijndaelManaged实例
 2 RijndaelManaged RMCrypto = new RijndaelManaged();
 3 //byte[] key = RMCrypto.Key;
 4 //byte[] IV = RMCrypto.IV;
 5 //初始化Key,IV
 6 byte[] Key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
 7 byte[] IV = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
 8
 9 Console.WriteLine("connecte successed! Enter the message to send:");
10 string sMessage = Console.ReadLine();
11 //把明文消息转换成UTF8编码的字节流,避免乱码
12 byte[] messageByte = Encoding.UTF8.GetBytes(sMessage);
13 //实例化一个MemoryStream用于存放加密后的数据流
14 MemoryStream mStream = new MemoryStream();
15 //创建用于加密的CryptoStream实例
16 CryptoStream CryptStream = new CryptoStream(mStream,
17 RMCrypto.CreateEncryptor(Key, IV),
18 CryptoStreamMode.Write);
19 //把明文消息字节流写入到CryptoStream中,进行加密处理
20 CryptStream.Write(messageByte,0,messageByte.Length);
21 //把CryptoStream中的数据更新到MemoryStream中
22 CryptStream.FlushFinalBlock();
23 //把加密后的数据流转换成字节流
24 byte[] encryptoByte = mStream.ToArray();

数据解密

 1 //创建一个MemoryStream实例,存放收到的加密数据字节流
 2 MemoryStream encryptoStream = new MemoryStream(encryptoByte);
 3 //创建RijndaelManaged实例
 4 RijndaelManaged RMCrypto = new RijndaelManaged();
 5 //byte[] key = RMCrypto.Key;
 6 //byte[] IV = RMCrypto.IV;
 7 //初始化Key,IV
 8 byte[] Key = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
 9 byte[] IV = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16 };
10
11
12 //创建用于解密的CryptoStream实例
13 CryptoStream CryptStream = new CryptoStream(encryptoStream,
14    RMCrypto.CreateDecryptor(Key, IV),
15    CryptoStreamMode.Read);
16
17 //创建StreamReader实例,从CryptoStream中读出数据,
18 //StreamReader默认使用UTF8编码读出的数据
19 StreamReader SReader = new StreamReader(CryptStream);
20
21 //输出解密后的消息.
22 Console.WriteLine("The decrypted original message: {0}",SReader.ReadToEnd());

4. 数据传输

数据传输使用的是TCP连接,.net平台也对Socket进行了很好的封装,使网络IO操作非常方便。在密文数据发送前被编码成Base64形式的字符串,一个是方便加密数据的正常显示,另一方面是便于数据接收端在接收字节流的数据时便于转码成字符串。Base64是用64个可打印的ASCII码字符来表示二进制数据,所以Base64字符串与字节流的转换是一对一的转换,即一个字符对应一个字节,这样在进行字节流与字符串间的转换时不会因编码方式的不同出现偏差,造成后续的解密操作出现异常。

客户端

 1 //创建TCP连接
 2 TcpClient TCP = new TcpClient("localhost", 11000);
 3
 4 //从TCP连接中获得网络数据流
 5 NetworkStream NetStream = TCP.GetStream();
 6
 7 //便于显示,将加密后的数据字节流转成Base64编码的字符串
 8 string encryptBase64 = Convert.ToBase64String(encryptoByte);
 9 //将字符串转成字节流
10 encryptoByte = Encoding.ASCII.GetBytes(encryptBase64);
11
12 //把加密后的数据写入到NetworkStream中,发送到服务端。
13 NetStream.Write(encryptoByte, 0, encryptoByte.Length);
14 Console.WriteLine("The encryptoed message: {0}", encryptBase64);
15 Console.WriteLine("The message was sent.");

服务端

 1 //初始化TCPListen绑定IP地址和监听端口
 2 TcpListener TCPListen = new TcpListener(IPAddress.Any, 11000);
 3
 4 //开始监听
 5 TCPListen.Start();
 6
 7 //每隔五秒钟,检查是否有连接
 8 while (!TCPListen.Pending())
 9 {
10     Console.WriteLine("Still listening. Will try in 5 seconds.");
11     Thread.Sleep(5000);
12 }
13
14 //接受TCP连接.
15 TcpClient TCP = TCPListen.AcceptTcpClient();
16
17 //为此连接创建NetworkStream.
18 NetworkStream NetStream = TCP.GetStream();
19
20 //循环从NetworkStream中读出数据
21 string encryptoString = "";
22 int bytes;
23 while (true)
24 {
25     byte[] byteMessage = new byte[10];
26     bytes = NetStream.Read(byteMessage, 0, 10);
27     if (bytes <= 0)
28     {
29         break;
30     }
31     //加密后的数据是通过Base64编码成字符串后发送,可直接通过ASCII编码将字节转成ASCII码字符
32     //组装成完整的Bas64编码的字符串
33     encryptoString += Encoding.ASCII.GetString(byteMessage,0,bytes);
34 }
35 Console.WriteLine("The Encryptoed Message: {0}", encryptoString);
36 //把Base64编码的字符串转换成字节流
37 byte[] encryptoByte = Convert.FromBase64String(encryptoString);

因CryptoStream类使用的派生自Stream的类进行初始化,所以在本示例程序中可以直接使用NetworStream替代MemoryStream创建CryptoStream示例。示例程序见MSDN-加密数据。示例程序使用MemoryStream是便于获得加密后的数据。

时间: 2024-10-18 01:52:53

C#实现网络传输数据加密的相关文章

Android 密钥保护和 C/S 网络传输安全理论指南

注:本文将着重讲解 Android KeyStore.so 库保护 app key / secret.HTTPS 原理及其防中间人***措施. 谈到 Android 安全性话题,Android Developers 官方网站给出了许多很好的建议和讲解,涵盖了存储数据.权限.网络.处理凭据.输入验证.处理用户数据.加密等方方面面,甚至对于动态加载代码也提供了建议,具体可以看看 training 的?security tips?章节.而今天,我想特别来讲一讲在 Android 密钥保护和 C/S 网

网络传输协议

网络传输协议 1.常见协议 1.HTTP.HTTPS 超文本传输协议 2.FTP 文件传输协议 3.SMTP 简单邮件传输协议 2.http协议 超文本传输协议(HTTP,HyperText Transfer Protocol) 网站是基于HTTP协议的, 例如网站的图片.CSS.JS等都是基于HTTP协议进行传输的. HTML Hypertext Markup Language HTTP协议是由从客户机到服务器的请求(Request)和从服务器到客户机的响应(Response)进行了约束和规范

【转】android实时视频网络传输方案总结(一共有五套)

最近研究了Android的实时视频网络传输问题,在视频处理方面花费了大量精力进行研究,总结出以下五套方案,并加以比较 以320×240大小的视频传输为例 方案 压缩率 压缩/传输方式 实时性 平均流量消耗  传输距离 用camera的回调函数发送原始的yuv420数据 0 无压缩,按帧传输 高(20~30 fps) 很高(6.5 Mbps)太恐怖了O_O  近距离有线或无线 用MediaRecorder对yuv420进行H264硬编码后发送 高(95%) 帧间压缩,视频流传输 高(20 fps)

使用加密解密技术和CA认证解决网络传输中的安全隐患

服务端:xuegod63.cn   IP:192.168.1.63 客户端:xuegod64.cn   IP:192.168.1.64   网络安全: 网络传输中的安全隐患-.   中间人攻击 全隐患:        解决方法 1.窃听-- >  加密 2.篡改 ->  哈西算法:MD5,sha1 (检查数据完整性) 3.伪装(钩鱼网站,伪装WIFI)  ->  身份认证(用户名/密码.数字证书) 4.网络中断 (内网冒冲网关,DDOS )  –>绑定静态arp地址: 加大服务器和

atitit.二进制数据无损转字符串网络传输

1. gbk的网络传输问题,为什么gbk不能使用来传输二进制数据 1 2. base64 2 3. iso-8859-1  (推荐) 2 4. utf-8 (不能使用) 2 1. gbk的网络传输问题,为什么gbk不能使用来传输二进制数据 gbk会造成信息丢失 由于有些字符在gbk字符集中找不到对应的字符,所以默认使用编码63代替,也就是?(问号)...gbk仅仅能兼容低位asc编码(英文字母),高位编码要使用来编码汉字了... 作者::老哇的爪子Attilax艾龙,EMAIL:[email p

Oracle工具之--ASM与文件系统及跨网络传输文件

Oracle工具之--ASM与文件系统及跨网络传输文件   Oracle DBMS_FILE_TRANSFER可以实现文件系统和ASM磁盘组之间实现文件传输及ASM磁盘组之间跨网络的传输. DBMS_FILE_TRANSFER:   The DBMS_FILE_TRANSFER package provides procedures to copy a binary file within a database or to transfer a binary file between datab

浅谈跨国网络传输

在这个大数据,云部署不断映入眼帘的时代,也许很多人作为公司IT架构的管理者都会觉得有些无助和迷惘.新兴的科技确实给日常的IT工作带来了便利,但亦带来了种种挑战和不可预期的困难. 数据的存储,传输的便利固然重要,但是数据的安全却要重要的多.你永远都不会希望把自己的核心数据放到公共的存储空间中,也随即诞生了私有云等一系列的概念,但是终究还是第三方的架构方案,这种不可控性随时都可发生. 对于跨国的数据传输,国内的网络提供商无论是电信和联通都无法给出完美的答案,因为国内伟大的防火墙的原因,速度慢之又慢,

Android网络传输中必用的两个加密算法:MD5 和 RSA (附java完成测试代码)

MD5和RSA是网络传输中最常用的两个算法,了解这两个算法原理后就能大致知道加密是怎么一回事了.但这两种算法使用环境有差异,刚好互补. 一.MD5算法 首先MD5是不可逆的,只能加密而不能解密.比如明文是yanzi1225627,得到MD5加密后的字符串是:14F2AE15259E2C276A095E7394DA0CA9  但不能由后面一大串倒推出yanzi1225627.因此可以用来存储用户输入的密码在服务器上.现在下载文件校验文件是否中途被篡改也是用的它,原理参见:http://blog.c

ASP.NET知识总结(1.网络传输层)

1.网络传输层 1应用层(HTTP.FTP.SMTP)报文Message 2传输层(TCP.UDP)报文段Segment,为运行在不同主机上的应用程序进程间提供数据 传输服务.通过套接字(Socket)实现. TCP(传输控制协议)面向连接的.可靠(应用:ftp.smtp.http等都是基于tcp) UDP(用户数据报协议)无连接的.不可靠的(数据报)应用:视频会议.网络电话. DNS解析.(速度快,能容忍部分数据丢失) 3网络层(IP)数据报datagram,把数据从一台主机移动到另一台主机,