萬盛學電腦網

 萬盛學電腦網 >> 健康知識 >> 安全第一:.NET加密技術指南

安全第一:.NET加密技術指南

  摘要:     ===================================     信息安全是計算機應用的首要問題之一,但目前關於.NET加密功能的范例卻少之又少。有鑒於此,本文探討了在.NET平台下加密/解密文件的一般過程,並提供了一個加密/解密文件的工具。   Web服務以不容置疑的態勢迅速發展,促使許多單位開始考慮.NET之類的開發平台。但是,出於對安全問題的擔心,一些單位總是對采用新技術心存顧慮。好在有許多成熟的安全和網絡技術,例如虛擬私有網絡(VPN)和防火牆等,能夠極大地提高Web服務應用的安全和性能,讓開發者擁有選擇安全技術的自由,而不是非得使用尚在發展之中的XML安全技術不可。   雖然安全是信息系統的首要問題,但有關.NET安全和加密工具的范例卻少之又少。看看大多數.NET書籍的目錄,找不到任何有關安全的題目,更不用說關於密碼系統的探討了。   有鑒於此,本文將介紹如何在VB開發中運用.NET的加密和密鑰生成類,提供一個可用來加密和解密文件的工具Cryption。有了這個工具,你就可以在硬盤上保存各種機密文件,例如所有的密碼/用戶名字信息、收支文件、以及其他想要保密的信息,還可以加密那些通過Internet發送的文件。加密技術的用途非常廣泛,你可以進一步定制本文提供的工具滿足某些特殊需要,例如增加批處理能力等。     一、兩類重要的安全威脅     攻擊和洩密是計算機面臨的兩大安全威脅。攻擊可能來自病毒,例如它會刪除文件、降低機器運行速度或引發其它安全問題。相比之下,洩密往往要隱蔽得多,它侵害的是你的隱私:未經授權訪問硬盤文件,截取通過Internet發送的郵件,等等。洩密還可能伴隨著攻擊,例如修改機密文件等。     針對洩密的最佳防范措施就是加密。有效的加密不僅杜絕了洩密,而且還防范了由洩密引發的攻擊。加密技術有時還用於通信過程中的身份驗證——如果某個用戶知道密碼,那麼他應該就是那個擁有這一身份的人。     然而必須說明的是,沒有一種防范洩密的安全技術是絕對堅固的,因為密碼有可能被未經授權的人獲得。     二、使用.NET加密功能的前提     首先,要想使用.NET的安全功能,,就必須用Imports語句引入加密用的包。試驗本文涉及的任何代碼之前,請在VB代碼窗口的頂部加入下列Imports語句:     Imports System.IO    Imports System.Text    Imports System.Security.Cryptography    第二,美國政府過去限制某些加密技術出口。雖然這些限制不再有效,.NET框架在Windows的出口版本中禁用了“高級”加密技術。如果你的Windows不帶高級加密能力,可以從微軟網站下載更新包:對於Windows 2000,安裝Service Pack 2包含的High Encryption Pack;對於NT,安裝Service Pack 6a。對於Windows ME、95、98的用戶,IE 5.5也包含了High Encryption Pack。       三、加密/解密工具概況     本文提供的工具可用來加密和解密文件,如果你急著給一些文件加密,只需直接啟動本文後面提供的工具即可,圖一就是Cryption工具的運行界面。      圖一   這個工具提供了一個用來輸入文件名字的文本框和一個輸入密鑰的文本框,通過便捷的用戶界面提供加密、解密和密鑰生成功能。在圖一中,上方的文本框用來輸入待加密/解密文件的名字;下面的文本框用來輸入8個字符的密碼。執行加密操作之後將生成一個新的文件,這個經過加密的文件和原始文件在同一目錄下,文件名字也和原始文件的一樣,但加上了“xx”後綴,例如,假設原始文件是MyFile.txt,則加密得到的文件是MyFilexx.txt。   加密好之後,原始文件不一定非刪除不可,但一般來說最好刪除,因為加密的根本目的就是為了隱藏原始文件的數據。如果要從加密後的文件恢復出原始文件,在上面的文本框中輸入MyFilexx.txt,然後提供密碼,Cryption工具將創建一個與原始文件一樣的MyFile.txt文件。也就是說,Cryption把文件名字後面的“xx”看作是要求解密密文的標志。     注意:加密文件之後如果忘記了用來加密該文件的密碼,再想恢復出原始文件就不可能了。當然,這與密碼本身的復雜程度有關,要想保證文件的安全,最好采用較復雜的密碼,例如混合運用字母、數字和特殊字符(如“$”符號等)。     .NET提供的加密技術不止一種,不過本文討論的主要是對稱加密。對稱加密也稱為私有密鑰加密,它的特點是加密和解密用的是同一個密鑰(實際上是同一種算法),解密方和加密方都有責任保障密碼的安全(對於公用密鑰、不對稱加密,密鑰一共有兩個,其中一個密鑰是公開的,這是當前公認最有效的加密技術,但就速度而言要比對稱加密算法慢不少)。     在正式利用.NET加密類加密文件之前,首先必須從用戶提供的密碼生成一個密鑰。密鑰可以利用Hash函數生成,Hash函數把用戶的密碼字符串轉換成一組類似隨機數序列的、無意義的數據,這組數據可作為密鑰使用,在加密過程中對原始數據進行唯一性變形處理。     例如,用密鑰加密數據的一種辦法是把原始數據的ASCII碼加上密鑰的ASCII碼:       密鑰:ab = ASCII: 97, 98    數據:merry = ASCII: 109, 101, 114, 114, 121    把這組數據的ASCII碼加上密鑰的ASCII碼(必要時重復使用密鑰),得到的加密結果是:         97 98 97 98 97      109 101 114 114 121    206 199 211 212 218      對於同樣的數據,Hash算法總是生成同樣的結果(這就是說,對於同一個密碼,同一Hash算法總是生成相同的bit序列)。實際上,在本文提供的代碼中,利用.NET的SHA1CryptoServiceProvider類的ComputeHash方法可以驗證這一點,例如,對於同一個輸入參數morph,任何時候該方法總是返回下面的結果:124,230,93,253,197,206,136,72。因此,如果有人知道密碼以及生成密鑰的算法,他也可以輕松地推算出密鑰。       四、執行加密/解密     .NET加密技術要求密鑰有確定的長度,例如,DES(Data Encryption Standard)函數要求密鑰的長度是64位,Rijndael則要求128、192或256位長度的密鑰。密鑰越長,加密強度越高。對於DES之外的加密算法,查詢LegalKeySizes屬性即可得到它允許的密鑰長度,包括MinSize(支持的最小密鑰長度)、MaxSize(最大密鑰長度)、SkipSize(增量)。SkipSize表示密鑰最大長度和最小長度之間可用長度的間隔,例如,Rijndael算法的SkipSize值是64位。     利用下面的代碼可以得到密鑰的長度信息:     ' 創建DES加密對象    Dim des As New DESCryptoServiceProvider()    Dim fd() As KeySizes    fd = des.LegalKeySizes() 'tells us the size(s), in bits    MsgBox("加密類型=" & des.ToString() & Chr(13) & "minsize = " & fd(0).MinSize & Chr(13) & _    "maxsize = " & fd(0).MaxSize & Chr(13) & "skipsize = " & fd(0).SkipSize)      運行上面的代碼,得到的結果是64、64、0(圖二)。如果把加密對象的聲明改成TripleDESCryptoServiceProvider(),得到的結果是128、192、64(圖三)。       圖二      圖三     說明:DES算法要求輸入一個8字節的密碼,但實際使用的密鑰只有56位(7個字節),每一個字節的最後一位不用(它作為校驗位使用,但不用於實際的加密過程)。     下面的代碼開始生成本文示例程序的密鑰:     Public Class Form1    Inherits System.Windows.Forms.Form        ' 保存密鑰的8字節的數組    Private TheKey(7) As Byte    ' 在向量中放入一些隨機數據    Private Vector() As Byte = {&H12, &H44, &H16, &HEE, &H88, &H15, &HDD, &H41}      首先,代碼定義了保存密鑰和初始向量(請參見稍後的詳細說明)的兩個變量。向量的初值這裡用隨機數據填充,當然,通過密碼和Hash算法也可以獲得向量的初值。下面的過程從用戶輸入的密碼創建出密鑰:         Sub CreateKey(ByVal strKey As String)        ' 保存密鑰的字節數組    Dim arrByte(7) As Byte        Dim AscEncod As New ASCIIEncoding()    Dim i As Integer = 0    AscEncod.GetBytes(strKey, i, strKey.Length, arrByte, i)    ' 獲得密碼的Hash值    Dim hashSha As New SHA1CryptoServiceProvider()    Dim arrHash() As Byte = hashSha.ComputeHash(arrByte)    ' 將Hash值保存到密鑰    For i = 0 To 7    TheKey(i) = arrHash(i)    Next i        End Sub                用戶的密碼(strKey)傳入到CreateKey過程,分解成一組ASCII值保存到一個字節數組。把這個字節數組傳遞給SHA1CryptoServiceProvider類的ComputeHash方法,返回一個Hash值。把這個Hash值保存到TheKey數組,供以後的加密/解密過程使用(注意S
copyright © 萬盛學電腦網 all rights reserved