第04章-數(shù)據(jù)流與數(shù)據(jù)加密和解密_第1頁
第04章-數(shù)據(jù)流與數(shù)據(jù)加密和解密_第2頁
第04章-數(shù)據(jù)流與數(shù)據(jù)加密和解密_第3頁
第04章-數(shù)據(jù)流與數(shù)據(jù)加密和解密_第4頁
第04章-數(shù)據(jù)流與數(shù)據(jù)加密和解密_第5頁
已閱讀5頁,還剩78頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

第04章-數(shù)據(jù)流與數(shù)據(jù)加密和解密第一頁,共83頁。2Ch04數(shù)據(jù)流與數(shù)據(jù)的加密和解密4.1數(shù)據(jù)編碼和解碼4.2數(shù)據(jù)流4.3數(shù)據(jù)加密與數(shù)字簽名第二頁,共83頁。4.1數(shù)據(jù)編碼和解碼4.1.1常見的字符集編碼方式4.1.2利用Encoding類實現(xiàn)編碼和解碼第三頁,共83頁。44.1.1常見的字符集編碼方式每個國家都有自己的字符編碼方式要想正確打開一個文件,必須知道它采用的是哪種編碼方式,否則就可能會出現(xiàn)亂碼。常見的字符集編碼方式:ASCIIUnicodeUTF-8GB2312和GB18030第四頁,共83頁。54.1.1常見的字符集編碼方式1.ASCIIASCII字符集由128個字符組成,包括大小寫字母、數(shù)字0~9、標(biāo)點符號、非打印字符(換行符、制表符等4個)以及控制字符(退格、響鈴等)。2.UnicodeUnicode是國際通用的編碼方式,可以表示地球上絕大部分地區(qū)的文字。這種編碼每個字符都占2個字節(jié),例如一個英文字符占2個字節(jié),一個漢字也是2個字節(jié)。C#中的字符和字符串默認(rèn)采用的都是Unicode編碼。第五頁,共83頁。64.1.1常見的字符集編碼方式3.UTF-8UTF-8是在因特網(wǎng)上使用最廣泛的一種編碼格式。它是Unicode的一種變長字符編碼,用1~4個字節(jié)表示一個Unicode字符。例如,每個英文字母都占1個字節(jié),每個漢字都占4個字節(jié)。4.GB2312和GB18030對于簡體中文來說,國家規(guī)定的編碼標(biāo)準(zhǔn)(國標(biāo))有兩種,一種是GB2312(1980年公布),另一種是GB18030(2000年公布)GB2312每個漢字的編碼長度都占2個字節(jié),這種編碼方式最多支持6千多個漢字的編碼;GB18030編碼長度為1~4個字節(jié),可支持兩萬多個漢字的編碼。第六頁,共83頁。74.1.2利用Encoding類實現(xiàn)編碼和解碼Encoding類位于System.Text命名空間下該類主要用于對字符集進(jìn)行編碼和解碼以及將一種編碼格式轉(zhuǎn)換為另一種編碼格式。Encoding類提供的常用屬性和方法:Default屬性獲取系統(tǒng)的當(dāng)前ANSI代碼頁的編碼BodyName屬性獲取可與郵件正文標(biāo)記一起使用的編碼名稱。如果當(dāng)前Encoding無法使用,則為空字符串HeaderName屬性獲取可與郵件標(biāo)題標(biāo)記一起使用的編碼名稱。如果當(dāng)前Encoding無法使用,則為空字符串Unicode屬性獲取Unicode格式的編碼(UTF-16)UTF8屬性獲取Unicode格式的編碼(UTF-8)ASCII屬性獲取ASCII字符集的編碼Convert方法將字節(jié)數(shù)組從一種編碼轉(zhuǎn)換為另一種編碼GetBytes方法將一組字符編碼為一個字節(jié)序列GetString方法將一個字節(jié)序列解碼為一個字符串GetEncoding方法返回指定格式的編碼第七頁,共83頁。84.1.2利用Encoding類實現(xiàn)編碼和解碼Encoding類的基本用法:1.獲取所有編碼名稱及其描述信息2.獲取指定編碼名稱及其描述信息3.不同編碼之間的轉(zhuǎn)換4.利用Encoding類實現(xiàn)字符串的編碼和解碼第八頁,共83頁。94.1.2利用Encoding類實現(xiàn)編碼和解碼1.獲取所有編碼名稱及其描述信息使用Encoding類靜態(tài)的GetEncodings方法可得到一個包含所有編碼的EncodingInfo類型的數(shù)組。EncodingInfo類同位于System.Text命名空間下,提供有關(guān)編碼的基本信息。foreach(EncodingInfoeiinEncoding.GetEncodings()){Encodingen=ei.GetEncoding();Console.WriteLine("編碼名稱:{0,-18},編碼描述:{1}",ei.Name,en.EncodingName);}第九頁,共83頁。104.1.2利用Encoding類實現(xiàn)編碼和解碼2.獲取指定編碼名稱及其描述信息Encoding類提供了UTF8、ASCII、Unicode等屬性,通過這些屬性可以獲取某個字符集編碼。也可以利用Encoding類靜態(tài)的GetEndcoing方法來獲取。Encodingascii=Encoding.ASCII;Encodinggb2312=Encoding.GetEncoding("GB2312");Encodinggb18030=Encoding.GetEncoding("GB18030");得到Encoding對象后,即可利用HeaderName屬性獲取編碼名稱,利用EncodingName屬性獲取編碼描述。strings1="GB2312的編碼名稱為:"+gb2312.HeaderName;strings2="GB2312的編碼描述為:"+gb2312.EncodingName;第十頁,共83頁。114.1.2利用Encoding類實現(xiàn)編碼和解碼3.不同編碼之間的轉(zhuǎn)換利用Encoding類的Convert方法可將字節(jié)數(shù)組從一種編碼轉(zhuǎn)換為另一種編碼,轉(zhuǎn)換結(jié)果為一個byte類型的數(shù)組。語法為:publicstaticbyte[]Convert(EncodingsrcEncoding,//源編碼

EncodingdstEncoding,//目標(biāo)編碼

byte[]bytes//待轉(zhuǎn)換的字節(jié)數(shù)組)第十一頁,共83頁。124.1.2利用Encoding類實現(xiàn)編碼和解碼3.不同編碼之間的轉(zhuǎn)換如將Unicode字符串轉(zhuǎn)換為UTF8字符串strings="abcd";Encodingunicode=Encoding.Unicode;Encodingutf8=Encoding.UTF8;byte[]b=Encoding.Convert(unicode,utf8,unicode.GetBytes(s));strings1=utf8.GetString(b);第十二頁,共83頁。134.1.2利用Encoding類實現(xiàn)編碼和解碼4.利用Encoding類實現(xiàn)字符串的編碼和解碼可以直接用Encoding類實現(xiàn)字符串的編碼和解碼例如:Encodingen=Encoding.GetEncoding("GB2312");//編碼byte[]bytes=en.GetBytes("abcd123");//按字節(jié)顯示編碼后的數(shù)據(jù)textBlock1.Text=BitConverter.ToString(bytes);//解碼textBlock2.Text=en.GetString(bytes);第十三頁,共83頁。144.1.2利用Encoding類實現(xiàn)編碼和解碼【例4-1】演示Encoding類的基本用法,運(yùn)行效果如圖4-1所示第十四頁,共83頁。4.2數(shù)據(jù)流4.2.1文件流()4.2.2內(nèi)存流(MemoryStream)4.2.3網(wǎng)絡(luò)流(NetworkStream)4.2.4加密流(CryptoStream)4.2.5StreamReader和StreamWriter類4.2.6BinaryReader和BinaryWriter類第十五頁,共83頁。164.2數(shù)據(jù)流數(shù)據(jù)流(Stream)是對串行傳輸數(shù)據(jù)的一種抽象表示當(dāng)希望通過網(wǎng)絡(luò)逐字節(jié)串行傳輸數(shù)據(jù),或者對文件逐字節(jié)進(jìn)行操作時,首先需要將數(shù)據(jù)轉(zhuǎn)化為數(shù)據(jù)流。System.IO命名空間下的Stream類是所有數(shù)據(jù)流的基類。數(shù)據(jù)流一般和某個外部數(shù)據(jù)源相關(guān)數(shù)據(jù)源可以是硬盤上的文件、外部設(shè)備(如I/O卡的端口)、內(nèi)存、網(wǎng)絡(luò)套接字等。第十六頁,共83頁。174.2數(shù)據(jù)流根據(jù)不同的數(shù)據(jù)源,可分別使用從Stream類派生的類對數(shù)據(jù)流進(jìn)行操作。類、MemoryStream類、NetworkStream類、CryptoStream類用于文本讀寫的StreamReader和StreamWriter類用于二進(jìn)制讀寫的BinaryReader和BinaryWriter類等。對數(shù)據(jù)流的操作有3種:逐字節(jié)順序?qū)懭耄▽?shù)據(jù)從內(nèi)存緩沖區(qū)傳輸?shù)酵獠吭矗┲鹱止?jié)順序讀?。▽?shù)據(jù)從外部源傳輸?shù)絻?nèi)存緩沖區(qū))隨機(jī)讀寫(從某個位置開始逐字節(jié)順序讀或?qū)懀5谑唔?,?3頁。184.2.1文件流()System.IO命名空間下的類繼承于Stream類利用類可以對各種類型的文件進(jìn)行讀寫例如:文本文件、可執(zhí)行文件、圖像文件、視頻文件等1.創(chuàng)建對象常用有兩種創(chuàng)建對象的辦法。(1)利用構(gòu)造函數(shù)創(chuàng)建對象(2)利用File類創(chuàng)建對象第十八頁,共83頁。194.2.1文件流()(1)利用構(gòu)造函數(shù)創(chuàng)建對象利用類的構(gòu)造函數(shù)創(chuàng)建對象語法為(stringpath,mode,access)參數(shù)中的path指定文件路徑;mode指定文件操作方式;access控制文件訪問權(quán)限。枚舉的可選值:CreateNew、Create、Open、OpenOrCreate、Truncate、Append枚舉的可選值有:Read、Write、ReadWrite第十九頁,共83頁。204.2.1文件流()(2)利用File類創(chuàng)建對象利用System.IO命名空間下的File類創(chuàng)建對象。利用OpenRead方法創(chuàng)建僅讀取的文件流;利用OpenWrite方法創(chuàng)建僅寫入的文件流。如,以僅讀取的方式打開文件。fs=(@"D:\ls\");第二十頁,共83頁。214.2.1文件流()2.讀寫文件得到對象后:可以利用該對象的Read方法讀取文件數(shù)據(jù)到字節(jié)數(shù)組中利用Write方法將字節(jié)數(shù)組中的數(shù)據(jù)寫入文件(1)Read方法對象的Read方法用于將文件中的數(shù)據(jù)讀到字節(jié)數(shù)組中語法如下,該方法返回從中實際讀取的字節(jié)數(shù)。publicoverrideintRead(byte[]array,//保存從文件流中實際讀取的數(shù)據(jù)intoffset,//向array數(shù)組中寫入數(shù)據(jù)的起始位置,一般為0intcount//希望從文件流中讀取的字節(jié)數(shù))第二十一頁,共83頁。224.2.1文件流()(2)Write方法對象的Write方法用于將字節(jié)數(shù)組寫入到文件中語法如下:publicoverridevoidWrite(byte[]buffer,//要寫入到文件流中的數(shù)據(jù)

intoffset,//從buffer中讀取的起始位置

intsize//寫入到流中的字節(jié)數(shù))【例4-2】演示類的基本用法第二十二頁,共83頁。234.2.2內(nèi)存流(MemoryStream)利用System.IO命名空間下的MemoryStream類,可以按內(nèi)存流的方式對保存在內(nèi)存中的字節(jié)數(shù)組進(jìn)行操作:利用Write方法將字節(jié)數(shù)組寫入到內(nèi)存流中利用Read方法將內(nèi)存流中的數(shù)據(jù)讀取到字節(jié)數(shù)組中MemoryStream的用法與文件流的用法相似,支持對數(shù)據(jù)流的查找和隨機(jī)訪問。該對象的CanSeek屬性值默認(rèn)為true程序中可通過Position屬性獲取內(nèi)存流的當(dāng)前位置。由于內(nèi)存流的容量可自動增長,因此在數(shù)據(jù)加密以及對長度不定的數(shù)據(jù)進(jìn)行緩存等場合,使用內(nèi)存流比較方便?!纠?-3】演示MemoryStream的基本用法第二十三頁,共83頁。244.2.3網(wǎng)絡(luò)流(NetworkStream)System.Net.Sockets命名空間下的NetworkStream類也是從Stream類繼承而來的,利用它可以通過網(wǎng)絡(luò)發(fā)送或接收數(shù)據(jù)??梢詫etworkStream看作在數(shù)據(jù)源和接收端之間架設(shè)了一個數(shù)據(jù)通道,這樣一來,讀取和寫入數(shù)據(jù)就可以針對這個通道來進(jìn)行。注意NetworkStream類僅支持面向連接的套接字。對于NetworkStream流,寫入操作是指從來源端內(nèi)存緩沖區(qū)到網(wǎng)絡(luò)上的數(shù)據(jù)傳輸;讀取操作是從網(wǎng)絡(luò)上到接收端內(nèi)存緩沖區(qū)(如字節(jié)數(shù)組)的數(shù)據(jù)傳輸。第二十四頁,共83頁。254.2.3網(wǎng)絡(luò)流(NetworkStream)一旦構(gòu)造了NetworkStream對象,就可以使用它通過網(wǎng)絡(luò)發(fā)送和接收數(shù)據(jù)。如圖所示為利用網(wǎng)絡(luò)流發(fā)送及接收TCP數(shù)據(jù)的流程。其中,Write方法負(fù)責(zé)將字節(jié)數(shù)組從進(jìn)程緩沖區(qū)發(fā)送到本機(jī)的TCP發(fā)送緩沖區(qū)然后TCP/IP協(xié)議棧再通過網(wǎng)絡(luò)適配器把數(shù)據(jù)真正發(fā)送到網(wǎng)絡(luò)上最終到達(dá)接收方的TCP接收緩沖區(qū)。第二十五頁,共83頁。264.2.3網(wǎng)絡(luò)流(NetworkStream)使用NetworkStream對象時,需要注意以下幾點:通過DataAvailable屬性,可查看緩沖區(qū)中是否有數(shù)據(jù)等待讀出。網(wǎng)絡(luò)流沒有當(dāng)前位置的概念,不支持對數(shù)據(jù)流的查找和隨機(jī)訪問,NetworkStream對象的CanSeek屬性始終返回false讀取Position屬性和調(diào)用Seek方法時,都會引發(fā)NotSupportedException異常。第二十六頁,共83頁。274.2.3網(wǎng)絡(luò)流(NetworkStream)1.獲取NetworkStream對象有兩種獲取NetworkStream對象的辦法。(1)利用TcpClient對象的GetStream方法得到網(wǎng)絡(luò)流對象。TcpClienttcpClient=newTcpClient();tcpClient.Connect("",51888);NetworkStreamnetworkStream=client.GetStream();(2)利用Socket得到網(wǎng)絡(luò)流對象。NetworkStreammyNetworkStream=newNetworkStream(mySocket);第二十七頁,共83頁。284.2.3網(wǎng)絡(luò)流(NetworkStream)2.發(fā)送數(shù)據(jù)NetworkStream類的Write/Read方法的語法格式和文件流相同Write方法為同步方法,在將數(shù)據(jù)寫入到網(wǎng)絡(luò)流之前,Write方法將一直處于阻塞狀態(tài),直到發(fā)送成功或者返回異常為止如:檢查NetworkStream是否可寫,如果可寫,則使用Write寫入一條消息。if(myNetworkStream.CanWrite){byte[]writeBuffer=Encoding.UTF8.GetBytes("Hello");myNetworkStream.Write(writeBuffer,0,writeBuffer.Length);}else{......}第二十八頁,共83頁。294.2.3網(wǎng)絡(luò)流(NetworkStream)3.接收數(shù)據(jù)接收方通過調(diào)用Read方法將數(shù)據(jù)從接收緩沖區(qū)讀取到進(jìn)程緩沖區(qū),完成讀取操作。如:使用DataAvailable來確定是否有數(shù)據(jù)可供讀取,當(dāng)有可用數(shù)據(jù)時,將從NetworkStream讀取數(shù)據(jù)。第二十九頁,共83頁。304.2.3網(wǎng)絡(luò)流(NetworkStream)if(myNetworkStream.CanRead){byte[]readBuffer=newbyte[1024];//設(shè)置緩沖區(qū)大小intnumberOfBytesRead=0;//準(zhǔn)備接收的信息有可能會大于1024,所以要用循環(huán)

do{numberOfBytesRead=myNetworkStream.Read(readBuffer,0,readBuffer.Length);......//處理接收到數(shù)據(jù)}while(myNetworkStream.DataAvailable);}else{......}第三十頁,共83頁。314.2.4加密流(CryptoStream)CryptoStream類位于System.Security.Cryptography命名空間下該類可按加密流的方式加密或者解密數(shù)據(jù),而且只能用于對稱加密。實現(xiàn)CryptoStream的任何被加密的對象都可以和實現(xiàn)Stream的任何對象鏈接起來,因此一個對象的流式處理輸出可以饋送到另一個對象的輸入,而不需要分別存儲中間結(jié)果。第三十一頁,共83頁。324.2.4加密流(CryptoStream)調(diào)用構(gòu)造函數(shù)創(chuàng)建CryptoStream對象時,需用目標(biāo)數(shù)據(jù)流、要使用的轉(zhuǎn)換和流的模式初始化CryptoStream類的新實例。加密時為寫訪問模式,解密時為讀訪問模式。CryptoStream類的構(gòu)造函數(shù)語法如下:publicCryptoStream(Streamstream, //對其執(zhí)行加密轉(zhuǎn)換的流ICryptoTransformtransform,//要對流執(zhí)行的加密轉(zhuǎn)換CryptoStreamModemode//CryptoStreamMode枚舉,有Read和Write兩種)第三十二頁,共83頁。334.2.4加密流(CryptoStream)使用CryptoStream對象時,一般還要借助其他流進(jìn)行處理。比如使用作為目標(biāo)數(shù)據(jù)流,再根據(jù)創(chuàng)建的CryptoStream對象生成StreamWriter對象,然后調(diào)用WriteLine方法,通過CryptoStream將加密后的數(shù)據(jù)寫入,寫入完成后,關(guān)閉創(chuàng)建的對象。此時在文件中保存的就是加密后的數(shù)據(jù)。解密時,使用和加密時相同的密鑰創(chuàng)建CryptoStream實例,并在創(chuàng)建該實例時將構(gòu)造函數(shù)的mode參數(shù)改為讀模式,再將StreamWriter替換成StreamReader,即可將解密后的數(shù)據(jù)讀取出來。第三十三頁,共83頁。344.2.4加密流(CryptoStream)但是,這里還存在以下幾個問題沒有解決:使用哪種加密算法來加密數(shù)據(jù)?加密流只能用于對稱加密,而對稱加密是什么意思?如何加密和解密數(shù)據(jù)?在數(shù)據(jù)加密與數(shù)字簽名一節(jié)的例子中,再講解。第三十四頁,共83頁。354.2.5StreamReader和StreamWriter類NetworkStream、MemoryStream和類都提供了以字節(jié)為基本單位的讀寫方法。其實現(xiàn)思路都是先將待寫入的數(shù)據(jù)轉(zhuǎn)化為字節(jié)序列,然后再進(jìn)行讀寫。這對文本數(shù)據(jù)來說用起來很不方便。操作文本數(shù)據(jù)時,一般用StreamReader和StreamWriter類來實現(xiàn)。第三十五頁,共83頁。364.2.5StreamReader和StreamWriter類NetworkStream、MemoryStream和類都提供了以字節(jié)為基本單位的讀寫方法。其實現(xiàn)思路都是先將待寫入的數(shù)據(jù)轉(zhuǎn)化為字節(jié)序列,然后再進(jìn)行讀寫。這對文本數(shù)據(jù)來說用起來很不方便。操作文本數(shù)據(jù)時,一般用StreamReader和StreamWriter類來實現(xiàn)。第三十六頁,共83頁。374.2.5StreamReader和StreamWriter類1.創(chuàng)建StreamReader和StreamWriter的實例如果數(shù)據(jù)來源是文件流、內(nèi)存流或者網(wǎng)絡(luò)流,可以利用StreamReader和StreamWriter對象的構(gòu)造函數(shù)得到讀寫流。NetworkStreamnetworkStream=client.GetStream();StremReadersr=newStremReader(networkStream);......StreamWritersw=newStreamWriter(networkStream);......第三十七頁,共83頁。384.2.5StreamReader和StreamWriter類1.創(chuàng)建StreamReader和StreamWriter的實例如果需要處理的是文件流,還可以直接利用文件路徑創(chuàng)建StreamWriter對象。StreamWritersw=newStreamWriter("C:\\");與該方法等價的有File及類提供的CreateText方法。StreamWritersw=("C:\\");第三十八頁,共83頁。394.2.5StreamReader和StreamWriter類2.讀寫文本數(shù)據(jù)利用StreamWriter類,可以用類似Console.Write和Console.WriteLine的辦法寫入文本數(shù)據(jù)利用StreamReader類,用類似Console.Read和Console.ReadLine的辦法讀取文本數(shù)據(jù)。讀寫完成后,不要忘記用Close方法關(guān)閉流,或者用using語句讓系統(tǒng)自動關(guān)閉它。第三十九頁,共83頁。404.2.6BinaryReader和BinaryWriter類System.IO命名空間還提供了BinaryReader和BinaryWriter類以二進(jìn)制模式讀寫流,更方便于對圖像文件、壓縮文件等二進(jìn)制數(shù)據(jù)進(jìn)行操作。對于BinaryReader中的每個讀方法,在BinaryWriter中都有一個與之對應(yīng)的寫方法。比如BinaryReader提供了ReadByte、ReadBoolean、ReadInt、ReadInt16、ReadDouble、ReadString等方法BinaryWriter則提供了多個重載的Write方法分別與之對應(yīng)。例如,當(dāng)Write方法傳遞的參數(shù)為Int32類型時,利用BinaryWriter類的Write方法可以將Int32類型數(shù)據(jù)轉(zhuǎn)化為長度為4的字節(jié)數(shù)組,并將字節(jié)流傳遞給一個Stream對象。第四十頁,共83頁。414.2.6BinaryReader和BinaryWriter類System.IO命名空間還提供了BinaryReader和BinaryWriter類以二進(jìn)制模式讀寫流,更方便于對圖像文件、壓縮文件等二進(jìn)制數(shù)據(jù)進(jìn)行操作。對于BinaryReader中的每個讀方法,在BinaryWriter中都有一個與之對應(yīng)的寫方法。比如BinaryReader提供了ReadByte、ReadBoolean、ReadInt、ReadInt16、ReadDouble、ReadString等方法與之對應(yīng)BinaryWriter則提供了多個重載的Write方法分別與之對應(yīng)。第四十一頁,共83頁。4.3數(shù)據(jù)加密與數(shù)字簽名4.3.1對稱加密4.3.2不對稱加密4.3.3密鑰容器4.3.4數(shù)字簽名第四十二頁,共83頁。4.3數(shù)據(jù)加密與數(shù)字簽名數(shù)據(jù)在網(wǎng)絡(luò)傳輸過程中的保密性是網(wǎng)絡(luò)安全中重點要考慮的問題之一。網(wǎng)絡(luò)數(shù)據(jù)在不安全的信道上傳輸?shù)?,最好的辦法就是對數(shù)據(jù)進(jìn)行加密和解密處理,從而保證數(shù)據(jù)的完整性和安全性。例如:即使不是通過網(wǎng)絡(luò)傳輸加密后的數(shù)據(jù),我們也會經(jīng)常對字符串、文件以及數(shù)據(jù)庫中的數(shù)據(jù)等信息進(jìn)行加密,比如登錄時要求輸入登錄密碼等。命名空間:System.Security.Cryptography命名空間這些加密算法主要分為兩大類:對稱加密和不對稱加密。第四十三頁,共83頁。4.3.1對稱加密對稱加密也稱為私鑰加密采用私鑰算法,加密和解密數(shù)據(jù)使用的是同一個密鑰。由于具有密鑰的任意一方都可以使用該密鑰解密數(shù)據(jù),因此必須保證該密鑰不能被攻擊者獲取,否則就失去了加密的意義。私鑰算法以塊為單位加密數(shù)據(jù)一次加密一個數(shù)據(jù)塊,所以也稱為塊密碼。私鑰加密算法與公鑰算法相比速度非???,當(dāng)加密數(shù)據(jù)流時,私鑰加密是最理想的方式。第四十四頁,共83頁。4.3.1對稱加密1.常見的對稱加密算法常見的對稱加密(私鑰加密)算法有多種:(1)DES和TripleDES加密算法(2)RC2加密算法(3)SHA-1加密算法(4)AES加密算法第四十五頁,共83頁。4.3.1對稱加密(1)DES和TripleDES加密算法DES是美國1977年公布的一種數(shù)據(jù)加密標(biāo)準(zhǔn),該算法目前已經(jīng)有多種破解方法,已被淘汰。TripleDES算法(也叫3DES算法)是美國國家標(biāo)準(zhǔn)技術(shù)研究所(NIST)1999年提出的數(shù)據(jù)加密標(biāo)準(zhǔn)。該算法是DES的一個變形,使用DES算法的3次連續(xù)迭代,支持128位和192位的密鑰長度,其安全性比DES算法高。(2)RC2加密算法RC2算法是RonRivest在1987年設(shè)計的一個塊密碼算法。該算法密鑰長度為從40位~128位,以8位遞增。第四十六頁,共83頁。4.3.1對稱加密(3)SHA-1加密算法SHA-1(安全哈希算法,也稱為安全哈希標(biāo)準(zhǔn))是由美國政府發(fā)布的一種加密哈希算法??梢愿鶕?jù)任意長度的字符串生成160位的哈希值。HMACSHA1接受任何大小的密鑰,并產(chǎn)生長度為160位的哈希序列。第四十七頁,共83頁。4.3.1對稱加密(4)AES加密算法1997年美國國家標(biāo)準(zhǔn)技術(shù)協(xié)會(NIST)開始向全世界公開征集新的高級加密標(biāo)準(zhǔn)(AdvancedEncryptionStandard,AES)Rijndael算法是由VincentRijmen和JoanDaemen兩人提出的加密算法。該算法作為新一代的數(shù)據(jù)加密標(biāo)準(zhǔn),匯聚了強(qiáng)安全性、高性能、高效率、易用和靈活等優(yōu)點。算法支持128位(16個字節(jié))、192位(24個字節(jié))和256位(32個字節(jié))的密鑰長度,與DES算法相比,Rijndael的128位密鑰比DES的56位密鑰強(qiáng)1021倍。由于Rijndael加密算法是AES選中的唯一算法,因此將其簡稱為AES算法。第四十八頁,共83頁。4.3.1對稱加密2.對稱加密的實現(xiàn)原理所有對稱加密(私鑰加密)算法都是通過加密將n字節(jié)的輸入塊轉(zhuǎn)換為加密字節(jié)的輸出塊。加密和解密字節(jié)序列都必須逐塊進(jìn)行而且讀入的數(shù)據(jù)塊必須符合私鑰算法要求的塊的大小,如果不符合應(yīng)該填充至使其符合要求。例如,RC2、DES和TripleDES每塊均為8字節(jié),AES為16字節(jié)(默認(rèn))、24字節(jié)或32字節(jié)。如果被加密的數(shù)據(jù)塊大于n,則逐塊加密,即一次加密一個塊。如果被加密的數(shù)據(jù)塊小于n,則先將其擴(kuò)展為n字節(jié)后再進(jìn)行加密處理。第四十九頁,共83頁。4.3.1對稱加密(1)用于加密的塊密碼模式塊密碼加密模式可以根據(jù)需要通過CipherMode枚舉來選擇using(Aesaes=Aes.Create()){aes.Mode=CipherMode.CBC;......}CipherMode枚舉提供的可選值有CBC、CFB、CTS、ECB、OFB,如果不設(shè)置,默認(rèn)為CBC模式。第五十頁,共83頁。4.3.1對稱加密CBC:密碼塊鏈模式。在該模式中,每個純文本塊在加密前,都和前一個塊進(jìn)行按位“異或”操作。這樣可確保即使純文本包含許多相同的塊,這些塊中的每一個也會加密為不同的密碼文本塊。在加密塊之前,初始化向量(IV)通過按位“異或”操作與第一個純文本塊結(jié)合。如果密碼文本塊中有一個位出錯,相應(yīng)的純文本塊也將出錯。此外,后面的塊中與原出錯位的位置相同的位也將出錯。第五十一頁,共83頁。4.3.1對稱加密CFB:密碼反饋模式。該模式將少量遞增的純文本處理成密碼文本,而不是一次處理整個塊。這種模式將一個塊分為幾部分,每部分都用移位寄存器對其進(jìn)行處理。例如,如果塊大小為8個字節(jié),移位寄存器每次處理一個字節(jié),則該塊將被分為8個部分。如果密碼文本中有一個位出錯,則將導(dǎo)致接下來若干次遞增的純文本也出錯,直到出錯位從移位寄存器中移出為止。默認(rèn)反饋大小可以根據(jù)算法而變,但通常是8位或塊大小的位數(shù)支持CFB的算法可使用FeedbackSize屬性設(shè)置反饋位數(shù)。第五十二頁,共83頁。4.3.1對稱加密CTS:密碼文本竊用模式。該模式可處理任何長度的純文本并產(chǎn)生長度與純文本長度相匹配的密碼文本。除了最后兩個純文本塊外,對于所有其他塊,此模式與CBC模式的行為相同。第五十三頁,共83頁。4.3.1對稱加密ECB:電子密碼本模式。該模式分別加密每個塊。任何純文本塊只要相同并且在同一消息中,或者在使用相同的密鑰加密的不同消息中,都將被轉(zhuǎn)換成同樣的密碼文本塊。需要特別注意的是,由于該模式存在多個安全隱患,不建議使用此模式。這是因為如果要加密的純文本包含大量重復(fù)的塊,則逐塊破解密碼文本是可行的。另外,攻擊者還可以對塊進(jìn)行分析來確定加密密鑰。此外,隨時準(zhǔn)備攻擊的對手甚至可能會在密文發(fā)送過程中悄悄插入、替代或交換個別的塊,從而導(dǎo)致結(jié)果與預(yù)想的情況大相徑庭。第五十四頁,共83頁。4.3.1對稱加密OFB:輸出反饋模式。該模式將少量遞增的純文本處理成密碼文本,而不是一次處理整個塊。此模式與CFB相似;這兩種模式的唯一差別是移位寄存器的填充方式不同。如果密碼文本中有一個位出錯,純文本中相應(yīng)的位也將出錯。但是,如果密碼文本中有多余或者缺少的位,則那個位之后的純文本都將出錯。第五十五頁,共83頁。4.3.1對稱加密(2)密鑰Key和初始化向量IV.NET類庫中提供的塊密碼加密模式默認(rèn)使用CBC模式。該模式通過一個密鑰Key和一個初始化向量(InitializationVector,IV)對數(shù)據(jù)執(zhí)行加密轉(zhuǎn)換。必須知道這個密鑰和初始化向量才能加密和解密數(shù)據(jù)。既然有了密鑰Key,為什么還要再使用一個初始化向量IV呢?第五十六頁,共83頁。4.3.1對稱加密既然有了密鑰Key,為什么還要再使用一個初始化向量IV呢?這是因為初始化向量默認(rèn)是一個隨機(jī)生成的字符集,使用它可以確保任何兩個原始數(shù)據(jù)塊都不會生成相同的加密后的數(shù)據(jù)塊,從而可以盡可能防范窮舉搜索而進(jìn)行的攻擊。例如,對于給定的私鑰Key,如果不用初始化向量IV,那么相同的明文輸入塊就會加密為同樣的密文輸出塊。顯然,如果在明文流中有重復(fù)的塊,那么在密文流中也會存在重復(fù)的塊。對于攻擊者來說,就可以對這些重復(fù)的塊進(jìn)行分析或者通過窮舉來發(fā)現(xiàn)密鑰。為了解決這個問題,加密時先使用初始化向量IV加密第一個純文本塊,然后每個后續(xù)純文本塊都會在加密前與前一個密碼文本塊進(jìn)行按位“異或”(XOR)運(yùn)算。因此,每個密碼文本塊都依賴于它前面的塊。這樣一來,兩個相同的明文塊的輸出就會不同,從而使數(shù)據(jù)的安全系數(shù)大大提高。第五十七頁,共83頁。4.3.1對稱加密3.對稱加密的優(yōu)缺點對稱加密的優(yōu)點是加密、解密速度快,適合大量數(shù)據(jù)的加密和解密處理。缺點是由于加密和解密使用的是同一個密鑰,解密方必須知道密鑰才能解密,如果攻擊者得到了密鑰,也就等于知道了如何解密數(shù)據(jù)。因此,在實際的網(wǎng)絡(luò)應(yīng)用編程中,如何安全保存密鑰以及在網(wǎng)絡(luò)傳輸中如何將密鑰傳遞給對方是解決對稱加密問題的關(guān)鍵。第五十八頁,共83頁。4.3.1對稱加密4.利用AES算法加密解密字符串加密和解密數(shù)據(jù)時,有兩種實現(xiàn)思路:一種是程序根據(jù)用戶提供的密碼,用某種對稱加密算法實現(xiàn)加密和解密,這種方式適用于讓用戶去記憶密碼的情況。另一種是隨機(jī)生成對稱加密的密鑰,然后用它加密和解密數(shù)據(jù),這種方式適用于對本機(jī)中的重要數(shù)據(jù)或者對通過網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)進(jìn)行加密和解密的場合。在System.Security.Cryptography命名空間有一個Aes類該類是高級加密標(biāo)準(zhǔn)(AES)的所有實現(xiàn)都必須從中繼承的抽象基類,利用它可直接實現(xiàn)基于AES算法的加密和解密。第五十九頁,共83頁。4.3.1對稱加密(1)利用用戶提供的密碼和AES算法加密解密數(shù)據(jù)【例4-4】演示利用AES算法加密解密字符串的基本用法當(dāng)然,利用AES算法不僅僅能加密解密字符串,還可以用它加密解密各種數(shù)據(jù),包括對文件進(jìn)行加密和解密等唯一的要求是都需要先將被加密或解密的數(shù)據(jù)轉(zhuǎn)換為字節(jié)數(shù)組,然后對字節(jié)數(shù)組進(jìn)行處理。第六十頁,共83頁。4.3.1對稱加密(2)利用隨機(jī)產(chǎn)生的密鑰和AES算法加密解密數(shù)據(jù)【例4-5】演示利用隨機(jī)產(chǎn)生的密鑰加密和解密字符串的基本用法第六十一頁,共83頁。4.3.2不對稱加密不對稱加密也叫公鑰加密。這種技術(shù)使用不同的加密密鑰與解密密鑰是一種“由已知加密密鑰推導(dǎo)出解密密鑰在計算上是不可行的”密碼體制。不對稱加密產(chǎn)生的主要原因有兩個:一是為了解決對稱加密的密鑰管理問題;二是數(shù)字簽名需要用不對稱加密來實現(xiàn)。第六十二頁,共83頁。4.3.2不對稱加密1.不對稱加密的實現(xiàn)原理不對稱加密使用一個需要保密的私鑰和一個可以對外公開的公鑰,即使用“公鑰/私鑰”對來加密和解密數(shù)據(jù)。公鑰和私鑰都在數(shù)學(xué)上相關(guān)聯(lián);用公鑰加密的數(shù)據(jù)只能用私鑰解密,反之,用私鑰加密的數(shù)據(jù)只能用公鑰解密。兩個密鑰對于通信會話都是唯一的。公鑰加密算法也稱為不對稱算法,原因是需要用一個密鑰加密數(shù)據(jù)而需要用另一個密鑰來解密數(shù)據(jù)。第六十三頁,共83頁。4.3.2不對稱加密注意:對稱加密算法使用長度可變的緩沖區(qū),而不對稱加密算法使用固定大小的緩沖區(qū),無法像私鑰算法那樣將數(shù)據(jù)鏈接起來成為流。不對稱加密之所以不容易被攻擊,關(guān)鍵在于對私鑰的管理上。在對稱加密中,發(fā)送方必須先將解密密鑰傳遞給接收方,接收方才能解密。如果能通過某種處理,避免通過網(wǎng)絡(luò)傳遞私鑰,就可以解決這個問題,不對稱加密的關(guān)鍵就在于此。第六十四頁,共83頁。4.3.2不對稱加密使用不對稱加密算法加密數(shù)據(jù)后,私鑰不是發(fā)送方傳遞給接收方的,而是接收方先生成一個公鑰/私鑰對,在接收被加密的數(shù)據(jù)前,先將該公鑰傳遞給發(fā)送方。由于從公鑰推導(dǎo)出私鑰是不可能的,所以不怕通過網(wǎng)絡(luò)傳遞時被攻擊者截獲公鑰從而推導(dǎo)出私鑰。發(fā)送方得到此公鑰后,使用此公鑰加密數(shù)據(jù),再將加密后的數(shù)據(jù)通過網(wǎng)絡(luò)傳遞給接收方;接收方收到加密后的數(shù)據(jù)后,再用私鑰進(jìn)行解密。由于沒有直接傳遞私鑰,從而保證了數(shù)據(jù)的安全性。第六十五頁,共83頁。4.3.2不對稱加密2.常用的不對稱加密算法.NET框架提供了多種實現(xiàn)不對稱加密算法的類,支持的不對稱加密算法有:(1)RSA算法(2)ECC算法第六十六頁,共83頁。4.3.2不對稱加密(1)RSA算法RSA加密算法是一種非對稱加密算法1977年由當(dāng)時在麻省理工學(xué)院的RonRivest、AdiShamir和LeonardAdleman一起提出,RSA就是他們?nèi)诵帐祥_頭字母拼在一起組成的。從1978年開始,該算法在公鑰加密標(biāo)準(zhǔn)和電子商業(yè)中就已經(jīng)被廣泛使用。速度是RSA的缺陷,該算法一般只適用于少量數(shù)據(jù)的加密。在.NET框架中,System.Security.Cryptography命名空間下的RSACryptoServiceProvider類提供了RSA算法的實現(xiàn),利用它可實現(xiàn)不對稱加密、解密以及數(shù)字簽名。第六十七頁,共83頁。4.3.2不對稱加密(2)ECC算法ECC(EllipticCurvesCryptography,橢圓曲線算法)是一種公鑰加密算法與RSA算法相比,ECC算法可以使較短的密鑰達(dá)到相同的安全程度。與ECC相關(guān)的算法包括ECDSA算法、ECDH算法等。在.NET框架中,System.Security.Cryptography命名空間下的ECDiffieHellmanCng類提供了橢圓曲線ECDSA算法的下一代加密技術(shù)(CNG)的加密實現(xiàn),利用該類可直接用ECDSA算法實現(xiàn)不對稱加密和解密。第六十八頁,共83頁。4.3.3密鑰容器不論是對稱加密還是非對稱加密,都有如何保存密鑰的問題。比如我們常見的讓用戶自己記憶密碼的辦法,如果攻擊者也知道了該密碼,那么攻擊者也一樣可以用它來進(jìn)入系統(tǒng)或者利用它來解密數(shù)據(jù),這樣一來,加密也就失去了意義。所以,網(wǎng)絡(luò)傳輸中一般不使用讓用戶記憶密碼的辦法,而是自動產(chǎn)生密鑰。同時還必須有一種辦法,來確保密鑰存儲的安全性,這就是密鑰容器的用途。第六十九頁,共83頁。4.3.3密鑰容器1.用密鑰容器保存不對稱加密的密鑰密鑰容器最直接的用途是用它來保存不對稱加密的密鑰為了區(qū)分是哪一個密鑰容器,還需要給每個密鑰容器起一個名稱。在System.Security.Cryptography命名空間中,有一個CspParameters類,可以通過該類提供的屬性設(shè)置獲取密鑰容器的名稱。第七十頁,共83頁。4.3.3密鑰容器如,保存RSA不對稱加密的密鑰到密鑰容器中,以及從密鑰容器中獲取密鑰信息。注意,保存密鑰信息和獲取密鑰信息使用的是同一段代碼。publicstaticRSACryptoServiceProviderGenRSAFromContainer(stringContainerName){//創(chuàng)建CspParameters對象,指定密鑰容器的名稱,用于保存公鑰/私鑰對

CspParameterscp=newCspParameters();

//如果不存在名為containerName的密鑰容器,則創(chuàng)建它,并初始化cp//如果存在,則直接根據(jù)它原來保存的內(nèi)容初始化cp

cp.KeyContainerName=ContainerName;//使用CspParameters對象創(chuàng)建RSACryptoServiceProvider的實例RSACryptoServiceProviderrsa=newRSACryptoServiceProvider(cp);

returnrsa;}第七十一頁,共83頁。4.3.3密鑰容器使用密鑰容器保存密鑰信息的優(yōu)點是安全性高采用密鑰容器保存密鑰信息時,需要注意一個問題,即當(dāng)操作系統(tǒng)被破壞時,比如硬盤損壞或者被病毒感染,密鑰信息也會隨之丟失。為了防止丟失密鑰信息而導(dǎo)致原來被加密的數(shù)據(jù)無法解密,生成密鑰信息后,最好先將其導(dǎo)出為XML文件保存到某個安全的地方,或者保存到某個數(shù)據(jù)庫中,作為備用。當(dāng)出現(xiàn)密鑰信息丟失的情況時,再將XML文件保存的密鑰信息導(dǎo)入到密鑰容器中即可。這種保護(hù)措施和要求必須提供數(shù)據(jù)庫數(shù)據(jù)備份功能的保護(hù)措施類似。第七十二頁,共83頁。4.3.3密鑰容器可以用以下方法之一導(dǎo)出密鑰信息。(1)ToXMLString方法:返回密鑰信息的XML表示形式。(2)ExportPa

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論