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下的RijndaelManaged和CryptoStream类。前面提到.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是便于获得加密后的数据。

此文非原创

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

  1. c#网络传输

    接着前面简单讲的,给大家聊聊服务开发. 网络传输 先说网络传输开发,总体来说,可以看成4中模型 我们把传输过程看做网线,那么在通过传输的过程中.2边就涉及池化问题,也就是我们常见的异步传输. 在业务端 ...

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

    1.网络传输层 1应用层(HTTP.FTP.SMTP)报文Message 2传输层(TCP.UDP)报文段Segment,为运行在不同主机上的应用程序进程间提供数据 传输服务.通过套接字(Socket ...

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

    atitit.二进制数据无损转字符串网络传输 1. gbk的网络传输问题,为什么gbk不能使用来传输二进制数据 1 2. base64 2 3. iso-8859-1  (推荐) 2 4. utf-8 ...

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

    MD5和RSA是网络传输中最常用的两个算法,了解这两个算法原理后就能大致知道加密是怎么一回事了.但这两种算法使用环境有差异,刚好互补. 一.MD5算法 首先MD5是不可逆的,只能加密而不能解密.比如明 ...

  5. Android IOS WebRTC 音视频开发总结(五七)-- 网络传输上的一种QoS方案

    本文主要介绍一种QoS的解决方案,文章来自博客园RTC.Blacker,欢迎关注微信公众号blacker,更多详见www.rtc.help QoS出现的背景: 而当网络发生拥塞的时候,所有的数据流都有 ...

  6. udp 视频包网络传输花屏

    视频数据传输在传输层可以选择TCP或者UDP,TCP面向连接,传输中断,发送端是知道的.TCP传输的好处是不丢包,坏处是网络不太好的情况下会越堵越严重.UDP非面向连接,发送端只管发送数据,接收端有没 ...

  7. 网络传输速度bps与下载文件所需时间的换算

    相信很多同志都非常关注自己家的计算机上网的宽带是多少.关心单位上网的宽带是多少! 但是很多同志都经常误解网络传输速度,以至于责备网络接入商(电信.网通.铁通等单位)欺骗用户,限制上网的速度! 本文,就 ...

  8. App安全之网络传输安全

    移动端App安全如果按CS结构来划分的话,主要涉及客户端本身数据安全,Client到Server网络传输的安全,客户端本身安全又包括代码安全和数据存储安全.所以当我们谈论App安全问题的时候一般来说在 ...

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

    MD5和RSA是网络传输中最经常使用的两个算法,了解这两个算法原理后就能大致知道加密是怎么一回事了.但这两种算法使用环境有差异,刚好互补. 一.MD5算法 首先MD5是不可逆的,仅仅能加密而不能解密. ...

随机推荐

  1. A Simple Actions Recognition System

    1. Problem Definition There's no doubt that researches and applications on the foundation of videos ...

  2. BEA WebLogic Server 10 查看和配置日志

    查看和配置日志 WebLogic Server 内的每个子系统都可生成日志消息来传达其状态.例如,当启动 WebLogic Server 实例时,安全子系统会输出消息以报告其初始化状态.为了记录其子系 ...

  3. 3905 - Meteor

    The famous Korean internet company nhn has provided an internet-based photo service which allows The ...

  4. PureCSS框架

    http://www.tuicool.com/articles/iyiI32 Pure中的主要组件包括: 一个响应式网格,可根据需求定制. 一个基于 Normalize.css 的基础库,用于修复跨浏 ...

  5. C#中登录验证FormsAuthentication

    1:前台编写一个登录界面,这里为了简化,只有用户名和密码 代码如下: <form method="post" action="/User/CheckLogin&qu ...

  6. js验证 button 提交

    <form class="form-horizontal" role="form" action="member_add" metho ...

  7. 关于css雪碧图sprite

    天气转凉了,又开始贪恋暖暖的被窝了. 早上不想起床的时候在被窝里看了有关于雪碧图的视频. 1.使用场景 V导航条,登录框img标签多次载入,性能低 X大图banner按需加载,如果做成雪碧图一次加载就 ...

  8. Git CMD - rm: Remove files from the working tree and from the index

    命令格式 git rm [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch] [--quiet] [--] <file>…​ 命令参 ...

  9. 关于ios对rtsp格式的流媒体支持的一些官方说明

    ios明确不支持rtsp格式的流媒体,基于rtsp/rtp对通用性和防炎墙以及需要开新端口等额外影响稳定性和通用性的原因. 而对http流的视频支持是最好的.虽然有第三方的方式配合ffmpeg库,实现 ...

  10. android之回调函数的意义

    本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/17483273) 看完这篇文后大家可以看看这个http://blog. ...