第04章-数据流与数据的加密和解密_第1页
第04章-数据流与数据的加密和解密_第2页
第04章-数据流与数据的加密和解密_第3页
第04章-数据流与数据的加密和解密_第4页
第04章-数据流与数据的加密和解密_第5页
已阅读5页,还剩77页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、工业和信息化部工业和信息化部“十二五十二五”规划教材规划教材普通高等学校普通高等学校“十二五十二五”规划教材规划教材C#网络应用编程网络应用编程第第3版版第第4章章 数据流与数据的数据流与数据的加密和解密加密和解密2Ch04 数据流与数据的加密和解密数据流与数据的加密和解密4.1 数据编码和解码数据编码和解码4.2 数据流数据流4.3 数据加密与数字签名数据加密与数字签名4.1 数据编码和解码数据编码和解码l4.1.1 常见的字符集编码方式常见的字符集编码方式l4.1.2 利用利用Encoding类实现编码和解码类实现编码和解码44.1.1 常见的字符集编码方式常见的字符集编码方式l每个国家都

2、有自己的字符编码方式每个国家都有自己的字符编码方式l要想正确打开一个文件,必须知道它采用的是哪种编码方式,要想正确打开一个文件,必须知道它采用的是哪种编码方式,否则就可能会出现乱码。否则就可能会出现乱码。l常见的字符集编码方式常见的字符集编码方式:ASCIIUnicodeUTF-8GB2312和和GB1803054.1.1 常见的字符集编码方式常见的字符集编码方式l1ASCIIASCII字符集由字符集由128个字符组成,包括大小写字母、数字个字符组成,包括大小写字母、数字09、标点符号、非打印字符(换行符、制表符等标点符号、非打印字符(换行符、制表符等4个)以及控制字符个)以及控制字符(退格、

3、响铃等)。(退格、响铃等)。l2UnicodeUnicode是国际通用的编码方式,可以表示地球上绝大部分地区是国际通用的编码方式,可以表示地球上绝大部分地区的文字。这种编码每个字符都占的文字。这种编码每个字符都占2个字节,例如一个英文字符占个字节,例如一个英文字符占2个字节,一个汉字也是个字节,一个汉字也是2个字节。个字节。C#中的字符和字符串默认采用的都是中的字符和字符串默认采用的都是Unicode编码。编码。64.1.1 常见的字符集编码方式常见的字符集编码方式l3UTF-8UTF-8是在因特网上使用最广泛的一种编码格式。它是是在因特网上使用最广泛的一种编码格式。它是Unicode的一种变

4、长字符编码,用的一种变长字符编码,用14个字节表示一个个字节表示一个Unicode字符。例字符。例如,每个英文字母都占如,每个英文字母都占1个字节,每个汉字都占个字节,每个汉字都占4个字节。个字节。l4GB2312和和GB18030对于简体中文来说,国家规定的编码标准(国标)有两种,一种对于简体中文来说,国家规定的编码标准(国标)有两种,一种是是GB2312(1980年公布),另一种是年公布),另一种是GB18030(2000年公布)年公布)GB2312每个汉字的编码长度都占每个汉字的编码长度都占2个字节,这种编码方式最多支个字节,这种编码方式最多支持持6千多个汉字的编码;千多个汉字的编码;G

5、B18030编码长度为编码长度为14个字节,可支持两万多个汉字的编码。个字节,可支持两万多个汉字的编码。74.1.2 利用利用Encoding类实现编码和解码类实现编码和解码lEncoding类位于类位于System.Text命名空间下命名空间下l该类主要用于对字符集进行编码和解码以及将一种编码格式转该类主要用于对字符集进行编码和解码以及将一种编码格式转换为另一种编码格式。换为另一种编码格式。lEncoding类提供的常用属性和方法:类提供的常用属性和方法:Default属性获取系统的当前ANSI代码页的编码BodyName属性获取可与邮件正文标记一起使用的编码名称。如果当前Encoding无

6、法使用,则为空字符串HeaderName属性获取可与邮件标题标记一起使用的编码名称。如果当前Encoding无法使用,则为空字符串Unicode属性获取Unicode格式的编码(UTF-16)UTF8属性获取Unicode格式的编码(UTF-8)ASCII属性获取ASCII字符集的编码Convert方法将字节数组从一种编码转换为另一种编码GetBytes方法将一组字符编码为一个字节序列GetString方法将一个字节序列解码为一个字符串GetEncoding方法返回指定格式的编码84.1.2 利用利用Encoding类实现编码和解码类实现编码和解码lEncoding类的基本用法类的基本用法:1

7、获取所有编码名称及其描述信息获取所有编码名称及其描述信息2获取指定编码名称及其描述信息获取指定编码名称及其描述信息3不同编码之间的转换不同编码之间的转换4利用利用Encoding类实现字符串的编码和解码类实现字符串的编码和解码94.1.2 利用利用Encoding类实现编码和解码类实现编码和解码l1获取所有编码名称及其描述信息获取所有编码名称及其描述信息使用使用Encoding类静态的类静态的GetEncodings方法可得到一个包含所有方法可得到一个包含所有编码的编码的EncodingInfo类型的数组。类型的数组。EncodingInfo类同位于类同位于System.Text命名空间下,提

8、供有关编码命名空间下,提供有关编码的基本信息。的基本信息。foreach ( EncodingInfo ei in foreach ( EncodingInfo ei in Encoding.GetEncodingsEncoding.GetEncodings( )( ) Encoding en = ei.GetEncoding( ); Encoding en = ei.GetEncoding( ); Console.WriteLine( Console.WriteLine(编码名称:编码名称:0,-180,-18,编码描述:,编码描述:1, 1, ei.Name, en.EncodingNam

9、e);ei.Name, en.EncodingName); 104.1.2 利用利用Encoding类实现编码和解码类实现编码和解码l2获取指定编码名称及其描述信息获取指定编码名称及其描述信息Encoding类提供了类提供了UTF8、ASCII、Unicode等属性,通过这些等属性,通过这些属性可以获取某个字符集编码。属性可以获取某个字符集编码。也可以利用也可以利用Encoding类静态的类静态的GetEndcoing方法来获取方法来获取。Encoding ascii = Encoding ascii = Encoding.ASCIIEncoding.ASCII; ;Encoding gb23

10、12 = Encoding gb2312 = Encoding.GetEncoding(GB2312)Encoding.GetEncoding(GB2312); ;Encoding gb18030 = Encoding.GetEncoding(GB18030);Encoding gb18030 = Encoding.GetEncoding(GB18030);得到得到Encoding对象后,即可利用对象后,即可利用HeaderName属性获取编码名属性获取编码名称,利用称,利用EncodingName属性获取编码描述属性获取编码描述。string s1 = GB2312string s1 = G

11、B2312的编码名称为的编码名称为: + : + gb2312.HeaderNamegb2312.HeaderName; ;string s2 = GB2312string s2 = GB2312的编码描述为的编码描述为: + : + gb2312.EncodingNamegb2312.EncodingName; ;114.1.2 利用利用Encoding类实现编码和解码类实现编码和解码l3不同编码之间的转换不同编码之间的转换利用利用Encoding类的类的Convert方法方法可将字节数组从一种编码转换为可将字节数组从一种编码转换为另一种编码,转换结果为一个另一种编码,转换结果为一个byte

12、类型的数组。类型的数组。语法为语法为:public static byte public static byte ConvertConvert( ( Encoding srcEncoding, / Encoding srcEncoding, /源编码源编码 Encoding dstEncoding, /Encoding dstEncoding, /目标编码目标编码 byte bytes /byte bytes /待转换的字节数组待转换的字节数组) )124.1.2 利用利用Encoding类实现编码和解码类实现编码和解码l3不同编码之间的转换不同编码之间的转换如将如将Unicode字符串转换为

13、字符串转换为UTF8字符串字符串string s = abcd;string s = abcd;Encoding unicode = Encoding.Unicode;Encoding unicode = Encoding.Unicode;Encoding utf8 = Encoding.UTF8;Encoding utf8 = Encoding.UTF8;byte b = byte b = Encoding.ConvertEncoding.Convert(unicode, utf8, unicode.GetBytes(s);(unicode, utf8, unicode.GetBytes(s

14、);string s1 = utf8.GetString(b);string s1 = utf8.GetString(b);134.1.2 利用利用Encoding类实现编码和解码类实现编码和解码l4利用利用Encoding类实现字符串的编码和解码类实现字符串的编码和解码可以直接用可以直接用Encoding类实现字符串的编码和解码类实现字符串的编码和解码例如:例如:uEncoding en = Encoding.GetEncoding(GB2312);Encoding en = Encoding.GetEncoding(GB2312);u/编码编码ubyte bytes = en.GetByt

15、es(abcd123);byte bytes = en.GetBytes(abcd123);u/按字节显示编码后的数据按字节显示编码后的数据utextBlock1.Text = BitConverter.ToString(bytes); textBlock1.Text = BitConverter.ToString(bytes); u/解码解码utextBlock2.Text = en.GetString(bytes);textBlock2.Text = en.GetString(bytes);144.1.2 利用利用Encoding类实现编码和解码类实现编码和解码l【例【例4-1】演示】演示

16、Encoding类的基本用法,运行效果如图类的基本用法,运行效果如图4-1所示所示4.2 数据流数据流l4.2.1 文件流(文件流(FileStream)l4.2.2 内存流(内存流(MemoryStream)l4.2.3 网络流(网络流(NetworkStream)l4.2.4 加密流(加密流(CryptoStream)l4.2.5 StreamReader和和StreamWriter类类l4.2.6 BinaryReader和和BinaryWriter类类164.2 数据流数据流l数据流(数据流(Stream)是对串行传输数据的一种抽象表示)是对串行传输数据的一种抽象表示当希望通过网络逐字

17、节串行传输数据,或者对文件逐字节进行操当希望通过网络逐字节串行传输数据,或者对文件逐字节进行操作时,首先需要将数据转化为数据流。作时,首先需要将数据转化为数据流。lSystem.IO命名空间下的命名空间下的Stream类类是所有数据流的基类。是所有数据流的基类。l数据流一般和某个外部数据源相关数据流一般和某个外部数据源相关数据源可以是硬盘上的文件、外部设备(如数据源可以是硬盘上的文件、外部设备(如I/O卡的端口)、内存卡的端口)、内存、网络套接字等。、网络套接字等。174.2 数据流数据流l根据不同的数据源,可分别使用从根据不同的数据源,可分别使用从Stream类派生的类对数据类派生的类对数据

18、流进行操作流进行操作。FileStream类类、MemoryStream类类、NetworkStream类类、CryptoStream类类用于文本读写的用于文本读写的StreamReader和和StreamWriter类类用于二进制读写的用于二进制读写的BinaryReader和和BinaryWriter类等。类等。l对数据流的操作有对数据流的操作有3种:种:逐字节顺序写入(将数据从内存缓冲区传输到外部源)逐字节顺序写入(将数据从内存缓冲区传输到外部源)逐字节顺序读取(将数据从外部源传输到内存缓冲区)逐字节顺序读取(将数据从外部源传输到内存缓冲区)随机读写(从某个位置开始逐字节顺序读或写)。随

19、机读写(从某个位置开始逐字节顺序读或写)。184.2.1 文件流(文件流(FileStream)lSystem.IO命名空间下的命名空间下的FileStream类继承于类继承于Stream类类l利用利用FileStream类可以对各种类型的文件进行读写类可以对各种类型的文件进行读写例如例如:文本文件、可执行文件、图像文件、视频文件等文本文件、可执行文件、图像文件、视频文件等l1创建创建FileStream对象对象常用有两种创建常用有两种创建FileStream对象的办法。对象的办法。(1)利用构造函数创建)利用构造函数创建FileStream对象对象(2)利用)利用File类创建类创建File

20、Stream对象对象194.2.1 文件流(文件流(FileStream)l(1)利用构造函数创建)利用构造函数创建FileStream对象对象利用利用FileStream类的构造函数创建类的构造函数创建FileStream对象对象语法为语法为FileStream (string FileStream (string pathpath, FileMode , FileMode modemode, FileAccess , FileAccess accessaccess) ) u参数中的参数中的pathpath指定文件路径;指定文件路径;umodemode指定文件操作方式;指定文件操作方式;ua

21、ccessaccess控制文件访问权限。控制文件访问权限。FileMode枚举的可选值枚举的可选值:CreateNew、Create、Open、OpenOrCreate、Truncate、AppendFileAccess枚举的可选值有:枚举的可选值有:Read、Write、ReadWrite204.2.1 文件流(文件流(FileStream)l(2)利用)利用File类创建类创建FileStream对象对象利用利用System.IO命名空间下的命名空间下的File类创建类创建FileStream对象。对象。利用利用OpenRead方法方法创建仅读取的文件流;创建仅读取的文件流;利用利用Ope

22、nWrite方法方法创建仅写入的文件流。创建仅写入的文件流。u如,以仅读取的方式打开如,以仅读取的方式打开File1.txtFile1.txt文件。文件。 FileStream fs= File.OpenRead(D:lsFile1.txt); FileStream fs= File.OpenRead(D:lsFile1.txt); 214.2.1 文件流(文件流(FileStream)l2读写文件读写文件得到得到FileStream对象后对象后:u可以利用该对象的可以利用该对象的ReadRead方法方法读取文件数据到字节数组中读取文件数据到字节数组中u利用利用WriteWrite方法方法将字

23、节数组中的数据写入文件将字节数组中的数据写入文件l(1)Read方法方法FileStream对象的对象的Read方法用于将文件中的数据读到字节数组中方法用于将文件中的数据读到字节数组中语法如下语法如下,该方法返回从该方法返回从FileStream中实际读取的字节数。中实际读取的字节数。 public override int Read( public override int Read( byte array, / byte array, /保存从文件流中实际读取的数据保存从文件流中实际读取的数据 int offset, / int offset, / 向向arrayarray数组中写入数据的

24、起始位置,一般为数组中写入数据的起始位置,一般为0 0 int count / int count /希望从文件流中读取的字节数希望从文件流中读取的字节数 ) ) 224.2.1 文件流(文件流(FileStream)l(2)Write方法方法FileStream对象的对象的Write方法用于将字节数组写入到文件中方法用于将字节数组写入到文件中语法如下:语法如下: public override void Write( public override void Write( byte buffer, / byte buffer, /要写入到文件流中的数据要写入到文件流中的数据 int offs

25、et, /int offset, /从从bufferbuffer中读取的起始位置中读取的起始位置 int size /int size /写入到流中的字节数写入到流中的字节数 ) )l【例【例4-2】演示】演示FileStream类的基本用法类的基本用法234.2.2 内存流(内存流(MemoryStream)l利用利用System.IO命名空间下的命名空间下的MemoryStream类,可以按内存类,可以按内存流的方式对保存在内存中的字节数组进行操作流的方式对保存在内存中的字节数组进行操作:利用利用Write方法将字节数组写入到内存流中方法将字节数组写入到内存流中利用利用Read方法将内存流

26、中的数据读取到字节数组中方法将内存流中的数据读取到字节数组中lMemoryStream的用法与文件流的用法相似,支持对数据流的的用法与文件流的用法相似,支持对数据流的查找和随机访问查找和随机访问。该对象的该对象的CanSeek属性属性值默认为值默认为true程序中可通过程序中可通过Position属性属性获取内存流的当前位置。获取内存流的当前位置。由于内存流的容量可自动增长,因此在数据加密以及对长度不定由于内存流的容量可自动增长,因此在数据加密以及对长度不定的数据进行缓存等场合,使用内存流比较方便。的数据进行缓存等场合,使用内存流比较方便。l【例【例4-3】演示】演示MemoryStream的

27、基本用法的基本用法244.2.3 网络流(网络流(NetworkStream)lSystem.Net.Sockets命名空间下的命名空间下的NetworkStream类也是从类也是从Stream类继承而来的,利用它可以通过网络发送或接收数据。类继承而来的,利用它可以通过网络发送或接收数据。l可以将可以将NetworkStream看作在数据源和接收端之间架设了一个看作在数据源和接收端之间架设了一个数据通道,这样一来,读取和写入数据就可以针对这个通道来数据通道,这样一来,读取和写入数据就可以针对这个通道来进行。进行。注意注意NetworkStream类仅支持面向连接的套接字。类仅支持面向连接的套接

28、字。对于对于NetworkStream流,流,写入操作写入操作是指从来源端内存缓冲区到网是指从来源端内存缓冲区到网络上的数据传输;络上的数据传输;读取操作读取操作是从网络上到接收端内存缓冲区(如是从网络上到接收端内存缓冲区(如字节数组)的数据传输。字节数组)的数据传输。254.2.3 网络流(网络流(NetworkStream)l一旦构造了一旦构造了NetworkStream对象,就可以使用它通过网络发送对象,就可以使用它通过网络发送和接收数据。和接收数据。l如如图所示为利用网络流发送及接收图所示为利用网络流发送及接收TCP数据的流程。数据的流程。其中,其中,Write方法负责将字节数组从进程

29、缓冲区发送到本机的方法负责将字节数组从进程缓冲区发送到本机的TCP发送缓冲区发送缓冲区然后然后TCP/IP协议栈再通过网络适配器把数据真正发送到网络上协议栈再通过网络适配器把数据真正发送到网络上最终到达接收方的最终到达接收方的TCP接收缓冲区。接收缓冲区。264.2.3 网络流(网络流(NetworkStream)l使用使用NetworkStream对象时,需要对象时,需要注意注意以下几点:以下几点:通过通过DataAvailable属性属性,可查看缓冲区中是否有数据等待,可查看缓冲区中是否有数据等待读出。读出。网络流没有当前位置的概念,不支持对数据流的查找和随机网络流没有当前位置的概念,不支

30、持对数据流的查找和随机访问,访问,NetworkStream对象的对象的CanSeek属性始终返回属性始终返回false读取读取Position属性和调用属性和调用Seek方法时,都会引发方法时,都会引发NotSupportedException异常。异常。274.2.3 网络流(网络流(NetworkStream)l1获取获取NetworkStream对象对象l有两种获取有两种获取NetworkStream对象的办法。对象的办法。(1)利用)利用TcpClient对象的对象的GetStream方法得到网络流对象。方法得到网络流对象。TcpClient tcpClient=new TcpCli

31、ent( ); TcpClient tcpClient=new TcpClient( ); tcpClient.Connect(, 51888); tcpClient.Connect(, 51888); NetworkStream networkStream = client.GetStream( ); NetworkStream networkStream = client.GetStream( ); (2)利用)利用Socket得到网络流对象。得到网络流对象。NetworkStream myNetworkStream = new NetworkStream(mySocket);Networ

32、kStream myNetworkStream = new NetworkStream(mySocket);284.2.3 网络流(网络流(NetworkStream)l2发送数据发送数据lNetworkStream类的类的Write/Read方法的语法格式和文件流相同方法的语法格式和文件流相同lWrite方法为同步方法,方法为同步方法,在在将数据写入到网络流之前,将数据写入到网络流之前,Write方方法将一直处于阻塞状态,直到发送成功或者返回异常为止法将一直处于阻塞状态,直到发送成功或者返回异常为止如:如:检查检查NetworkStream是否可写是否可写,如果可写,则使用如果可写,则使用W

33、rite写入写入一条消息。一条消息。if (myNetworkStream.CanWrite) if (myNetworkStream.CanWrite) byte writeBuffer = Encoding.UTF8.GetBytes(Hello); byte writeBuffer = Encoding.UTF8.GetBytes(Hello); myNetworkStream.Write(writeBuffer, 0, writeBuffer.Length); myNetworkStream.Write(writeBuffer, 0, writeBuffer.Length); else

34、 else . . 294.2.3 网络流(网络流(NetworkStream)l3接收数据接收数据l接收方通过调用接收方通过调用Read方法将数据从接收缓冲区读取到进程缓冲方法将数据从接收缓冲区读取到进程缓冲区,完成读取操作。区,完成读取操作。如:如:使用使用DataAvailable来确定是否有数据可供读取来确定是否有数据可供读取,当有可用数当有可用数据时,将从据时,将从NetworkStream读取数据。读取数据。304.2.3 网络流(网络流(NetworkStream) if(myNetworkStream.CanRead) if(myNetworkStream.CanRead) b

35、yte readBuffer = new byte1024; / byte readBuffer = new byte1024; /设置缓冲区大小设置缓冲区大小 int numberOfBytesRead = 0; int numberOfBytesRead = 0; / / 准备接收的信息有可能会大于准备接收的信息有可能会大于10241024,所以要用循环,所以要用循环 do do numberOfBytesRead = myNetworkStream.Read(readBuffer, 0, numberOfBytesRead = myNetworkStream.Read(readBuffe

36、r, 0, readBuffer.Length); readBuffer.Length); . / . /处理接收到数据处理接收到数据 while(myNetworkStream.DataAvailable); while(myNetworkStream.DataAvailable); else else . . 314.2.4 加密流(加密流(CryptoStream)lCryptoStream类位于类位于System.Security.Cryptography命名空命名空间下间下l该类可按加密流的方式加密或者解密数据,而且只能用于对称该类可按加密流的方式加密或者解密数据,而且只能用于对称加

37、密。加密。l实现实现CryptoStream的任何被加密的对象都可以和实现的任何被加密的对象都可以和实现Stream的任何对象链接起来,因此一个对象的流式处理输出可以馈送的任何对象链接起来,因此一个对象的流式处理输出可以馈送到另一个对象的输入,而不需要分别存储中间结果。到另一个对象的输入,而不需要分别存储中间结果。324.2.4 加密流(加密流(CryptoStream)l调用构造函数创建调用构造函数创建CryptoStream对象时,需用目标数据流、要对象时,需用目标数据流、要使用的转换和流的模式初始化使用的转换和流的模式初始化CryptoStream类的新实例。加密类的新实例。加密时为写访

38、问模式,解密时为读访问模式。时为写访问模式,解密时为读访问模式。lCryptoStream类的构造函数语法如下类的构造函数语法如下:public CryptoStream(public CryptoStream( Stream stream, Stream stream,/对其执行加密转换的流对其执行加密转换的流 ICryptoTransform transform, / ICryptoTransform transform, /要对流执行的加密转换要对流执行的加密转换 CryptoStreamMode mode CryptoStreamMode mode /CryptoStreamMode

39、/CryptoStreamMode枚举,有枚举,有ReadRead和和WriteWrite两种两种) )334.2.4 加密流(加密流(CryptoStream)l使用使用CryptoStream对象时,一般还要借助其他流进行处理。对象时,一般还要借助其他流进行处理。比如使用比如使用FileStream作为目标数据流,作为目标数据流,再根据创建的再根据创建的CryptoStream对象生成对象生成StreamWriter对象,对象,然后调用然后调用WriteLine方法,通过方法,通过CryptoStream将加密后的数据写将加密后的数据写入入FileStream,写入完成后,关闭创建的对象。

40、写入完成后,关闭创建的对象。此时在文件中保存的就是加密后的数据。此时在文件中保存的就是加密后的数据。l解密时,使用和加密时相同的密钥创建解密时,使用和加密时相同的密钥创建CryptoStream实例,并实例,并在创建该实例时将构造函数的在创建该实例时将构造函数的mode参数改为读模式,再将参数改为读模式,再将StreamWriter替换成替换成StreamReader,即可将解密后的数据读,即可将解密后的数据读取出来。取出来。344.2.4 加密流(加密流(CryptoStream)l但是,这里还存在以下几个问题没有解决:但是,这里还存在以下几个问题没有解决:使用哪种加密算法来加密数据?使用哪

41、种加密算法来加密数据?加密流只能用于对称加密,而对称加密是什么意思?加密流只能用于对称加密,而对称加密是什么意思?如何加密和解密数据?如何加密和解密数据?l在数据加密与数字签名一节的例子中,再在数据加密与数字签名一节的例子中,再讲解讲解。354.2.5 StreamReader和和StreamWriter类类lNetworkStream、MemoryStream和和FileStream类都提供了以类都提供了以字节为基本单位的读写方法字节为基本单位的读写方法。其实现思路都是先将待写入的数据转化为字节序列,然后再进行其实现思路都是先将待写入的数据转化为字节序列,然后再进行读写读写。这对文本数据来说

42、用起来很不方便。这对文本数据来说用起来很不方便。l操作文本数据时,一般用操作文本数据时,一般用StreamReader和和StreamWriter类来类来实现。实现。364.2.5 StreamReader和和StreamWriter类类lNetworkStream、MemoryStream和和FileStream类都提供了以类都提供了以字节为基本单位的读写方法字节为基本单位的读写方法。其实现思路都是先将待写入的数据转化为字节序列,然后再进行其实现思路都是先将待写入的数据转化为字节序列,然后再进行读写读写。这对文本数据来说用起来很不方便。这对文本数据来说用起来很不方便。l操作文本数据时,一般用

43、操作文本数据时,一般用StreamReader和和StreamWriter类来类来实现。实现。374.2.5 StreamReader和和StreamWriter类类l1创建创建StreamReader和和StreamWriter的实例的实例l如果数据来源是文件流、内存流或者网络流,可以利用如果数据来源是文件流、内存流或者网络流,可以利用StreamReader和和StreamWriter对象的构造函数得到读写流。对象的构造函数得到读写流。NetworkStream networkStream = client.GetStream( ); NetworkStream networkStream

44、 = client.GetStream( ); StremReader sr = new StremReader (networkStream); StremReader sr = new StremReader (networkStream); .StreamWriter sw = new StreamWriter (networkStream); StreamWriter sw = new StreamWriter (networkStream); .384.2.5 StreamReader和和StreamWriter类类l1创建创建StreamReader和和StreamWriter的实

45、例的实例l如果需要处理的是文件流,还可以直接利用文件路径创建如果需要处理的是文件流,还可以直接利用文件路径创建StreamWriter对象。对象。StreamWriter sw= new StreamWriter (C:file1.txt); StreamWriter sw= new StreamWriter (C:file1.txt); l与该方法等价的有与该方法等价的有File及及FileInfo类提供的类提供的CreateText方法。方法。StreamWriter sw = File.CreateText (C:file1.txt);StreamWriter sw = File.Cre

46、ateText (C:file1.txt);394.2.5 StreamReader和和StreamWriter类类l2读写文本数据读写文本数据l利用利用StreamWriter类,可以用类似类,可以用类似Console.Write和和Console.WriteLine的办法写入文本数据的办法写入文本数据l利用利用StreamReader类,用类似类,用类似Console.Read和和Console.ReadLine的办法读取文本数据。的办法读取文本数据。l读写完成后,不要忘记用读写完成后,不要忘记用Close方法方法关闭流,或者用关闭流,或者用using语句语句让系统自动关闭它。让系统自动关

47、闭它。404.2.6 BinaryReader和和BinaryWriter类类lSystem.IO命名空间还提供了命名空间还提供了BinaryReader和和BinaryWriter类类以二进制模式读写流以二进制模式读写流,更方便更方便于于对图像文件、压缩文件等二进对图像文件、压缩文件等二进制数据进行操作。制数据进行操作。l对于对于BinaryReader中的每个读方法,在中的每个读方法,在BinaryWriter中都有一中都有一个与之对应的写方法个与之对应的写方法。比如比如BinaryReader提供了提供了ReadByte、ReadBoolean、ReadInt、ReadInt16、Rea

48、dDouble、ReadString等方法等方法BinaryWriter则提供了多个重载的则提供了多个重载的Write方法分别与之对应。方法分别与之对应。例如,当例如,当Write方法传递的参数为方法传递的参数为Int32类型时,利用类型时,利用BinaryWriter类的类的Write方法可以将方法可以将Int32类型数据转化为长度为类型数据转化为长度为4的字节数组,的字节数组,并将字节流传递给一个并将字节流传递给一个Stream对象。对象。414.2.6 BinaryReader和和BinaryWriter类类lSystem.IO命名空间还提供了命名空间还提供了BinaryReader和和

49、BinaryWriter类类以二进制模式读写流以二进制模式读写流,更方便更方便于于对图像文件、压缩文件等二进对图像文件、压缩文件等二进制数据进行操作。制数据进行操作。l对于对于BinaryReader中的每个读方法,在中的每个读方法,在BinaryWriter中都有一中都有一个与之对应的写方法个与之对应的写方法。比如比如BinaryReader提供了提供了ReadByte、ReadBoolean、ReadInt、ReadInt16、ReadDouble、ReadString等方法等方法与之对应与之对应BinaryWriter则提供了多个重载的则提供了多个重载的Write方法分别与之对方法分别与

50、之对应。应。4.3 数据加密与数字签名数据加密与数字签名l4.3.1 对称加密对称加密l4.3.2 不对称加密不对称加密l4.3.3 密钥容器密钥容器l4.3.4 数字签名数字签名4.3 数据加密与数字签名数据加密与数字签名l数据在网络传输过程中的保密性是网络安全中重点要考虑的问数据在网络传输过程中的保密性是网络安全中重点要考虑的问题之一。题之一。网络数据在不安全的信道上传输的,最好的办法就是对数据进行网络数据在不安全的信道上传输的,最好的办法就是对数据进行加密加密和和解密处理,从而保证数据的完整性和安全性。解密处理,从而保证数据的完整性和安全性。l例如:例如:即使不是通过网络传输加密后的数据

51、,我们也会经常对字符串、即使不是通过网络传输加密后的数据,我们也会经常对字符串、文件以及数据库中的数据等信息进行加密,比如登录时要求输入文件以及数据库中的数据等信息进行加密,比如登录时要求输入登录密码等。登录密码等。l命名空间:命名空间:System.Security.Cryptography命名空间命名空间l这些加密算法主要分为两大类:这些加密算法主要分为两大类:对称加密对称加密和和不对称加密不对称加密。4.3.1 对称加密对称加密l对称加密也称为私钥加密对称加密也称为私钥加密l采用私钥算法,加密和解密数据使用的是同一个密钥。采用私钥算法,加密和解密数据使用的是同一个密钥。由于具有密钥的任意

52、一方都可以使用该密钥解密数据,因此必须由于具有密钥的任意一方都可以使用该密钥解密数据,因此必须保证该密钥不能被攻击者获取,否则就失去了加密的意义。保证该密钥不能被攻击者获取,否则就失去了加密的意义。l私钥算法以私钥算法以块块为单位加密数据为单位加密数据一次加密一个数据块,所以也称为块密码。一次加密一个数据块,所以也称为块密码。l私钥加密算法与公钥算法相比速度非常快,当加密数据流时,私钥加密算法与公钥算法相比速度非常快,当加密数据流时,私钥加密是最理想的方式。私钥加密是最理想的方式。4.3.1 对称加密对称加密l1常见的对称加密算法常见的对称加密算法l常见的对称加密(私钥加密)算法有多种常见的对

53、称加密(私钥加密)算法有多种:(1)DES和和TripleDES加密算法加密算法(2)RC2加密算法加密算法(3)SHA-1加密算法加密算法(4)AES加密算法加密算法4.3.1 对称加密对称加密l(1)DES和和TripleDES加密算法加密算法DES是美国是美国1977年公布的一种数据加密标准年公布的一种数据加密标准,该算法目前已经有该算法目前已经有多种破解方法,已被淘汰。多种破解方法,已被淘汰。TripleDES算法(也叫算法(也叫3DES算法)是美国国家标准技术研究所(算法)是美国国家标准技术研究所(NIST)1999年提出的数据加密标准。年提出的数据加密标准。u该算法是该算法是DES

54、DES的一个变形,使用的一个变形,使用DESDES算法的算法的3 3次连续迭代,支持次连续迭代,支持128128位位和和192192位的密钥长度,其安全性比位的密钥长度,其安全性比DESDES算法高。算法高。l(2)RC2加密算法加密算法RC2算法是算法是Ron Rivest在在1987年设计的一个块密码算法。该算年设计的一个块密码算法。该算法密钥长度为从法密钥长度为从40位位128位,以位,以8位递增。位递增。4.3.1 对称加密对称加密l(3)SHA-1加密算法加密算法SHA-1(安全哈希算法,也称为安全哈希标准)是由美国政府发(安全哈希算法,也称为安全哈希标准)是由美国政府发布的一种加密

55、哈希算法。布的一种加密哈希算法。可以根据任意长度的字符串生成可以根据任意长度的字符串生成160位的哈希值。位的哈希值。HMACSHA1接接受任何大小的密钥,并产生长度为受任何大小的密钥,并产生长度为160位的哈希序列。位的哈希序列。4.3.1 对称加密对称加密l(4)AES加密算法加密算法1997年美国国家标准技术协会(年美国国家标准技术协会(NIST)开始向全世界公开征集)开始向全世界公开征集新的高级加密标准(新的高级加密标准(Advanced Encryption Standard,AES)Rijndael算法是由算法是由Vincent Rijmen和和Joan Daemen两人提出的两人

56、提出的加密算法。加密算法。该算法作为新一代的数据加密标准,汇聚了强安全性、高性能、该算法作为新一代的数据加密标准,汇聚了强安全性、高性能、高效率、易用和灵活等优点。高效率、易用和灵活等优点。算法支持算法支持128位(位(16个字节)、个字节)、192位(位(24个字节)和个字节)和256位(位(32个字节)的密钥长度,与个字节)的密钥长度,与DES算法相比,算法相比,Rijndael的的128位密钥位密钥比比DES的的56位密钥强位密钥强1021倍。倍。由于由于Rijndael加密算法是加密算法是AES选中的唯一算法,因此将其简称为选中的唯一算法,因此将其简称为AES算法。算法。4.3.1 对

57、称加密对称加密l2对称加密的实现原理对称加密的实现原理l所有对称加密(私钥加密)算法都是通过加密将所有对称加密(私钥加密)算法都是通过加密将n字节的输入字节的输入块转换为加密字节的输出块。块转换为加密字节的输出块。加密和解密字节序列都必须逐块进行加密和解密字节序列都必须逐块进行而且读入的数据块必须符合私钥算法要求的块的大小,如果不符而且读入的数据块必须符合私钥算法要求的块的大小,如果不符合应该填充至使其符合要求。合应该填充至使其符合要求。u例如,例如,RC2RC2、DESDES和和TripleDESTripleDES每块均为每块均为8 8字节,字节,AESAES为为1616字节(默认)字节(默

58、认)、2424字节或字节或3232字节。字节。如果被加密的数据块大于如果被加密的数据块大于n,则逐块加密,即一次加密一个块。,则逐块加密,即一次加密一个块。如果被加密的数据块小于如果被加密的数据块小于n,则先将其扩展为,则先将其扩展为n字节后再进行加密字节后再进行加密处理。处理。4.3.1 对称加密对称加密l(1)用于加密的块密码模式)用于加密的块密码模式块密码加密模式可以根据需要通过块密码加密模式可以根据需要通过CipherMode枚举来选择枚举来选择using (Aes aes = Aes.Create()using (Aes aes = Aes.Create() aes.Mode = C

59、ipherMode.CBC; aes.Mode = CipherMode.CBC; . . CipherMode枚举提供的可选值有枚举提供的可选值有CBC、CFB、CTS、ECB、OFB,如果不设置,默认为,如果不设置,默认为CBC模式。模式。4.3.1 对称加密对称加密lCBC:密码块链模式。:密码块链模式。在该模式中,每个纯文本块在加密前,都和前一个块进行按位在该模式中,每个纯文本块在加密前,都和前一个块进行按位“异或异或”操作。操作。这样可确保即使纯文本包含许多相同的块,这些块中的每一个也这样可确保即使纯文本包含许多相同的块,这些块中的每一个也会加密为不同的密码文本块。会加密为不同的密码

60、文本块。在加密块之前,初始化向量(在加密块之前,初始化向量(IV)通过按位)通过按位“异或异或”操作与第一操作与第一个纯文本块结合。个纯文本块结合。如果密码文本块中有一个位出错,相应的纯文本块也将出错。此如果密码文本块中有一个位出错,相应的纯文本块也将出错。此外,后面的块中与原出错位的位置相同的位也将出错。外,后面的块中与原出错位的位置相同的位也将出错。4.3.1 对称加密对称加密lCFB:密码反馈模式。:密码反馈模式。该模式将少量递增的纯文本处理成密码文本,而不是一次处理整该模式将少量递增的纯文本处理成密码文本,而不是一次处理整个块。个块。这种模式将一个块分为几部分,每部分都用移位寄存器对其

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论