在資料安全領域,對稱加密因其效能高、實作簡單而廣泛應用於檔案保護。Rijndael 作為 AES(Advanced Encryption Standard)的底層演算法,提供了區塊大小與金鑰長度的靈活配置,是 .NET Framework 中實作對稱加密的首選。本文將透過一個完整的 Windows Forms 範例,示範如何使用 RijndaelManaged 類別實現檔案的加密與解密,包含密碼驗證、檔案流處理、初始化向量(IV)管理以及錯誤處理等關鍵技術細節。
範例程式採用單一表單(Form1)架構,主要元件包括:
textBox1、textBox2)分別用於輸入來源檔案路徑與輸出檔案路徑textBox3),設定 PasswordChar 為 '$' 隱藏輸入,長度限制 8-16 字元button3)、儲存檔案(button4)、加密(button1)、解密(button2)checkBox1)控制操作完成後是否刪除來源檔案public void encryption(string password, string readFile, string writeFile)
{
try
{
// 密碼長度驗證(8-16 字元)
if (password.Length >= 8 && password.Length <= 16)
{
byte[] key = Encoding.Default.GetBytes(password);
byte[] iv = rij.IV; // 使用預設 IV
Rijndael crypt = Rijndael.Create();
ICryptoTransform transform = crypt.CreateEncryptor(key, iv);
// 建立輸出檔案流與加密流
using (FileStream fsWrite = new FileStream(writeFile, FileMode.Create))
using (CryptoStream cs = new CryptoStream(fsWrite, transform, CryptoStreamMode.Write))
using (FileStream fsRead = new FileStream(readFile, FileMode.Open))
{
int byteData;
while ((byteData = fsRead.ReadByte()) != -1)
{
cs.WriteByte((byte)byteData);
}
}
enresult = true;
MessageBox.Show("加密完成!");
}
else
{
MessageBox.Show("密碼長度必須為 8-16 字元!");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
關鍵點說明:
Encoding.Default.GetBytes 將密碼字串轉為位元組陣列作為金鑰RijndaelManaged.IV 屬性自動產生隨機初始化向量,確保相同明文加密結果不同CryptoStream 以串流方式處理資料,避免大檔案一次載入記憶體using 區塊確保資源正確釋放(原始碼使用手動 Close(),現代寫法建議改用 using)public void decryption(string password, string readFile, string writeFile)
{
try
{
if (password.Length >= 8 && password.Length <= 16)
{
byte[] key = Encoding.Default.GetBytes(password);
byte[] iv = rij.IV; // 必須與加密時相同的 IV
Rijndael crypt = Rijndael.Create();
ICryptoTransform transform = crypt.CreateDecryptor(key, iv);
using (FileStream fsRead = new FileStream(readFile, FileMode.Open))
using (CryptoStream cs = new CryptoStream(fsRead, transform, CryptoStreamMode.Read))
using (FileStream fsWrite = new FileStream(writeFile, FileMode.OpenOrCreate))
{
int byteData;
while ((byteData = cs.ReadByte()) != -1)
{
fsWrite.WriteByte((byte)byteData);
}
}
deresult = true;
MessageBox.Show("解密完成!");
}
else
{
MessageBox.Show("密碼長度必須為 8-16 字元!");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
重要提醒: 解密時必須使用與加密完全相同的 IV。範例中直接使用 rij.IV(類別層級欄位),若實際部署需將 IV 與加密檔案一同儲存(通常寫入檔案開頭),否則無法正確解密。
// 取得副檔名
private string getfileext(string filename)
{
try
{
string[] parts = filename.Split('.');
return parts.Length > 1 ? parts[1] : null;
}
catch { return null; }
}
// 刪除來源檔案
public void DeleteFile(string filename)
{
try { File.Delete(filename); }
catch (Exception ex) { MessageBox.Show(ex.ToString()); }
}
Rfc2898DeriveBytes (PBKDF2) 配合鹽值與迭代次數衍生金鑰CryptographicException, IOException)而非通用 Exceptionusing 陳述式確保 IDisposable 物件正確釋放專案包含標準的 Program.cs 進入點與 Form1.Designer.cs 設計器程式碼。建議將加密邏輯封裝為獨立的靜態工具類別(如 CryptoHelper),與 UI 解耦,方便單元測試與重複使用。
本範例展示了 C# 使用 System.Security.Cryptography 命名空間實作 Rijndael 對稱加密的基本流程。雖然程式碼可正常運作,但在生產環境中必須加強金鑰管理、IV 處理與完整性保護。理解這些基礎概念後,開發者可進一步探索 AES-GCM 等認證加密模式,構建更安全的資料保護方案。