.NET将CryptoAPI改編進.NET的System.Security.Cryptography名字空間,使密碼服務擺脫了SDK平台的神秘性,變成了簡單的.NET名字空間的使用。由于随着整個架構元件一起共享,密碼服務更容易實作了,現在僅僅需要學習System.Security.Cryptography名字空間的功能和用于解決特定方案的類。
.NET将原來獨立的API和SDK合并到一個架構中,這對于程式開發人員非常有利。
加密和解密的算法
System.Security.Cryptography名字空間包含了實作安全方案的類,例如加密和解密資料、管理密鑰、驗證資料的完整性并確定資料沒有被篡改等等。本文重點讨論加密和解密。
加密和解密的算法分為對稱(symmetric)算法和不對稱(asymmetric)算法。對稱算法在加密和解密資料時使用相同的密鑰和初始化矢量,典型的有DES、 TripleDES和Rijndael算法,它适用于不需要傳遞密鑰的情況,主要用于本地文檔或資料的加密。不對稱算法有兩個不同的密鑰,分别是公共密鑰和私有密鑰,公共密鑰在網絡中傳遞,用于加密資料,而私有密鑰用于解密資料。不對稱算法主要有RSA、DSA等,主要用于網絡資料的加密。
加密和解密本地文檔
下面的例子是加密和解密本地文本,使用的是Rijndael對稱算法。
對稱算法在資料流通過時對它進行加密。是以首先需要建立一個正常的流(例如I/O流)。文章使用FileStream類将文本檔案讀入位元組數組,也使用該類作為輸出機制。
接下來定義相應的對象變量。在定義SymmetricAlgorithm抽象類的對象變量時我們可以指定任何一種對稱加密算法提供程式。代碼使用的是Rijndael算法,但是很容易改為DES或者TripleDES算法。.NET使用強大的随機密鑰設定了提供程式的執行個體,選擇自己的密鑰是比較危險的,接受計算機産生的密鑰是一個更好的選擇,文中的代碼使用的是計算機産生的密鑰。
下一步,算法執行個體提供了一個對象來執行實際資料傳輸。每種算法都有CreateEncryptor和CreateDecryptor兩個方法,它們傳回實作ICryptoTransform接口的對象。
最後,現在使用BinaryReader的ReadBytes方法讀取源檔案,它會傳回一個位元組數組。BinaryReader讀取源檔案的輸入流,在作為CryptoStream.Write方法的參數時調用ReadBytes方法。指定的CryptoStream執行個體被告知它應該操作的下層流,該對象将執行資料傳遞,無論流的目的是讀或者寫。
下面是加密和解密一個文本檔案的源程式片斷:
namespace com.billdawson.crypto { class TextFileCrypt { public static void Main(string[] args) { string file = args[0]; string tempfile = Path.GetTempFileName(); //打開指定的檔案 FileStream fsIn = File.Open(file,FileMode.Open, FileAccess.Read); FileStream fsOut = File.Open(tempfile, FileMode.Open, FileAccess.Write); //定義對稱算法對象執行個體和接口 SymmetricAlgorithm symm = new RijndaelManaged(); ICryptoTransform transform = symm.CreateEncryptor(); CryptoStream cstream = new CryptoStream(fsOut,transform, ryptoStreamMode.Write); BinaryReader br = new BinaryReader(fsIn); // 讀取源檔案到cryptostream cstream.Write(br.ReadBytes((int)fsIn.Length),0,(int)fsIn.Length); cstream.FlushFinalBlock(); cstream.Close(); fsIn.Close(); fsOut.Close(); Console.WriteLine("created encrypted file {0}", tempfile); Console.WriteLine("will now decrypt and show contents"); // 反向操作--解密剛才加密的臨時檔案 fsIn = File.Open(tempfile,FileMode.Open,FileAccess.Read); transform = symm.CreateDecryptor(); cstream = new CryptoStream(fsIn,transform, CryptoStreamMode.Read); StreamReader sr = new StreamReader(cstream); Console.WriteLine("decrypted file text: " + sr.ReadToEnd()); fsIn.Close(); } } } 加密網絡資料 如果我有一個隻想自己看到的文檔,我不會簡單的通過e-mail發送給你。我将使用對稱算法加密它;如果有人截取了它,他們也不能閱讀該文檔,因為他們沒有用于加密的唯一密鑰。但是你也沒有密鑰。我需要使用某種方式将密鑰給你,這樣你才能解密文檔,但是不能冒密鑰和文檔被截取的風險。 非對稱算法就是一種解決方案。這類算法使用的兩個密鑰有如下關系:使用公共密鑰加密的資訊隻能被相應的私有密鑰解密。是以,我首要求你給我發送你的公共密鑰。在發送給我的途中可能有人會截取它,但是沒有關系,因為他們隻能使用該密鑰給你的資訊加密。我使用你的公共密鑰加密文檔并發送給你。你使用私有密鑰解密該文檔,這是唯一可以解密的密鑰,并且沒有通過網絡傳遞。 不對稱算法比對稱算法計算的花費多、速度慢。是以我們不希望線上對話中使用不對稱算法加密所有資訊。相反,我們使用對稱算法。下面的例子中我們使用不對稱加密來加密對稱密鑰。接着就使用對稱算法加密了。實際上安全接口層(SSL)建立伺服器和浏覽器之間的安全對話使用的就是這種工作方式。 示例是一個TCP程式,分為伺服器端和用戶端。伺服器端的工作流程是: 從用戶端接收公共密鑰。 使用公共密鑰加密未來使用的對稱密鑰。 将加密了的對稱密鑰發送給用戶端。 給用戶端發送使用該對稱密鑰加密的資訊。 代碼如下:
|