加密文件
要加密文件,請(qǐng)按照下列步驟操作:
1. 啟動(dòng) Visual Studio 2005 或 Visual Studio .NET。
2. 單擊“項(xiàng)目”下的“Visual C#”,然后單擊“模板”下的“控制臺(tái)應(yīng)用程序”。Visual C# .NET 為您創(chuàng)建一個(gè)靜態(tài)類,以及一個(gè)空的 Main() 過
程。
3. 對(duì)以下命名空間使用 using 語句(如以下示例代碼中所示): • System
• System.Security
• System.Security.Cryptography
• System.Text
• System.IO
這樣,在后面的代碼中就不必從這些命名空間中限定聲明了。這些語句必須位于任何其他聲明之前。using System;
using System.IO;
using System.Security;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
using System.Text;
4. 生成密鑰以加密和解密數(shù)據(jù)。DESCryptoServiceProvider 基于一種對(duì)稱加密算法。對(duì)稱加密需要密鑰和初始化矢量 (IV) 來加密數(shù)據(jù)。要解密該數(shù)
據(jù),您必須擁有此同一密鑰和 IV。您還必須使用相同的加密算法。您可以使用下列方法之一生成密鑰: • 方法 1 您可以提示用戶輸入密碼。然后,
將此密碼用作密鑰和 IV。
• 方法 2 當(dāng)您創(chuàng)建對(duì)稱加密類的新實(shí)例時(shí),將為會(huì)話自動(dòng)創(chuàng)建一個(gè)新的密鑰和 IV。使用由受管理的對(duì)稱加密類生成的密鑰和 IV 來加密和解密文件。
5. 添加以下函數(shù)為會(huì)話生成一個(gè)新的密鑰(按照步驟 4 的方法 2 中的說明):// Call this function to remove the key from memory after use
for security.
[System.Runtime.InteropServices.DllImport("KERNEL32.DLL", EntryPoint="RtlZeroMemory")]
public static extern bool ZeroMemory(ref string Destination, int Length);
// Function to Generate a 64 bits Key.
static string GenerateKey()
{
// Create an instance of Symetric Algorithm. Key and IV is generated automatically.
DESCryptoServiceProvider desCrypto =(DESCryptoServiceProvider)DESCryptoServiceProvider.Create();
// Use the Automatically generated key for Encryption.
return ASCIIEncoding.ASCII.GetString(desCrypto.Key);
}
6. 在您的類中創(chuàng)建一個(gè)命名為 EncryptFile 的方法。EncryptFile 類必須具有以下 3 個(gè)參數(shù): • sInputFilename
• sOutputFilename
• sKey(用于加密和解密文件的密鑰。)
static void EncryptFile(string sInputFilename,
string sOutputFilename,
string sKey)
7. 在 EncryptFile 過程中,創(chuàng)建一個(gè)輸入 FileStream 對(duì)象和一個(gè)輸出 FileStream 對(duì)象。這些對(duì)象可以從目標(biāo)文件中讀取和向其中寫入。
FileStream fsInput = new FileStream(sInputFilename,
FileMode.Open,
FileAccess.Read);
FileStream fsEncrypted = new FileStream(sOutputFilename,
FileMode.Create,
FileAccess.Write);
8. 聲明一個(gè) DESCryptoServiceProvider 類的實(shí)例。這表示對(duì)文件使用的實(shí)際加密和解密技術(shù)。此時(shí),如果您更喜歡使用 RSAsecutiry 或另一種加密
技術(shù),則可以創(chuàng)建一個(gè)不同的提供程序。DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
9. 必須以字節(jié)數(shù)組的形式給加密提供程序提供密鑰。System.Text 命名空間提供了一個(gè)名為 GetBytes() 的函數(shù)。GetBytes() 函數(shù)的編碼特征之一是
,它取一個(gè)字符串,然后返回一個(gè)字節(jié)數(shù)組。各種加密技術(shù)采用的密鑰長(zhǎng)度是不相同的。例如,數(shù)據(jù)加密標(biāo)準(zhǔn) (DES) 使用等于 8 個(gè)字節(jié)或 8 個(gè)字符
的 64 位密鑰。
如果您不提供密鑰,提供程序就會(huì)隨機(jī)生成一個(gè)密鑰。這將成功地加密文件,但是無法解密文件。請(qǐng)注意,您還必須提供初始化矢量 (IV)。該值用作
加密的一部分。與密鑰相似,如果您未提供 IV,提供程序就會(huì)隨機(jī)生成一個(gè)。由于該值對(duì)于加密和解密必須相同,所以不能讓提供程序隨機(jī)生成這些
值。DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
10. 創(chuàng)建一個(gè) CryptoStream 類的實(shí)例,方法是:使用加密提供程序獲得一個(gè)加密對(duì)象(CreateEncryptor),并將現(xiàn)有的輸出 FileStream 對(duì)象作為
構(gòu)造函數(shù)的一部分。ICryptoTransform desencrypt = DES.CreateEncryptor();
CryptoStream cryptostream = new CryptoStream(fsEncrypted,
desencrypt,
CryptoStreamMode.Write);
11. 讀入輸入文件,然后寫出到輸出文件。傳遞 CryptoStream 對(duì)象,文件將使用您提供的密鑰加密。byte[] bytearrayinput = new byte
[fsInput.Length - 1];
fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
解密文件
要解密文件,請(qǐng)按照下列步驟操作:
1. 創(chuàng)建一個(gè)方法,然后將它命名為 DecryptFile。解密過程與加密過程相似,但 DecryptFile 過程與 EncryptFile 過程有兩個(gè)關(guān)鍵區(qū)別。 •
CryptoStream 對(duì)象是使用 CreateDecryptor 而非 CreateEncryptor 創(chuàng)建的,這將指定對(duì)象的使用方式。
• 在將解密的文本寫入到目標(biāo)文件時(shí),CryptoStream 對(duì)象現(xiàn)在是源,而不是目標(biāo)流。
static void DecryptFile(string sInputFilename,
string sOutputFilename,
string sKey)
{
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
//A 64 bit key and IV is required for this provider.
//Set secret key For DES algorithm.
DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
//Set initialization vector.
DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
//Create a file stream to read the encrypted file back.
FileStream fsread = new FileStream(sInputFilename,
FileMode.Open,
FileAccess.Read);
//Create a DES decryptor from the DES instance.
ICryptoTransform desdecrypt = DES.CreateDecryptor();
//Create crypto stream set to read and do a
//DES decryption transform on incoming bytes.
CryptoStream cryptostreamDecr = new CryptoStream(fsread,
desdecrypt,
CryptoStreamMode.Read);
//Print the contents of the decrypted file.
StreamWriter fsDecrypted = new StreamWriter(sOutputFilename);
fsDecrypted.Write(new StreamReader(cryptostreamDecr).ReadToEnd());
fsDecrypted.Flush();
fsDecrypted.Close();
}
2. 將以下幾行添加到 Main() 過程,以調(diào)用 EncryptFile 和 DecryptFile:static void Main()
{
// Must be 64 bits, 8 bytes.
// Distribute this key to the user who will decrypt this file.
string sSecretKey;
// Get the key for the file to encrypt.
sSecretKey = GenerateKey();
// For additional security pin the key.
GCHandle gch = GCHandle.Alloc( sSecretKey,GCHandleType.Pinned );
// Encrypt the file.
EncryptFile(@"C:\MyData.txt",
@"C:\Encrypted.txt",
sSecretKey);
// Decrypt the file.
DecryptFile(@"C:\Encrypted.txt",
@"C:\Decrypted.txt",
sSecretKey);
// Remove the key from memory.
ZeroMemory(gch.AddrOfPinnedObject(), sSecretKey.Length * 2);
gch.Free();
}
3. 保存文件。運(yùn)行您的應(yīng)用程序。確保輸入文件名使用的路徑指向一個(gè)現(xiàn)有文件。
測(cè)試過程
用一個(gè)文本文件 (.txt) 測(cè)試此代碼,確認(rèn)它可對(duì)此文件進(jìn)行正確的加密和解密。確保將文件解密到一個(gè)新文件(如本文中的 Main() 過程中所示),
而不是解密到原來的文件中。檢查解密后的文件,然后與原文件進(jìn)行比較。
完整代碼列表
using System;
using System.IO;
using System.Security;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
using System.Text;
namespace CSEncryptDecrypt
{
class Class1
{
// Call this function to remove the key from memory after use for security
[System.Runtime.InteropServices.DllImport("KERNEL32.DLL", EntryPoint="RtlZeroMemory")]
public static extern bool ZeroMemory(IntPtr Destination, int Length);
// Function to Generate a 64 bits Key.
static string GenerateKey()
{
// Create an instance of Symetric Algorithm. Key and IV is generated automatically.
DESCryptoServiceProvider desCrypto =(DESCryptoServiceProvider)DESCryptoServiceProvider.Create();
// Use the Automatically generated key for Encryption.
return ASCIIEncoding.ASCII.GetString(desCrypto.Key);
}
static void EncryptFile(string sInputFilename,
string sOutputFilename,
string sKey)
{
FileStream fsInput = new FileStream(sInputFilename,
FileMode.Open,
FileAccess.Read);
FileStream fsEncrypted = new FileStream(sOutputFilename,
FileMode.Create,
FileAccess.Write);
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
ICryptoTransform desencrypt = DES.CreateEncryptor();
CryptoStream cryptostream = new CryptoStream(fsEncrypted,
desencrypt,
CryptoStreamMode.Write);
byte[] bytearrayinput = new byte[fsInput.Length];
fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
cryptostream.Close();
fsInput.Close();
fsEncrypted.Close();
}
static void DecryptFile(string sInputFilename,
string sOutputFilename,
string sKey)
{
DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
//A 64 bit key and IV is required for this provider.
//Set secret key For DES algorithm.
DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
//Set initialization vector.
DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
//Create a file stream to read the encrypted file back.
FileStream fsread = new FileStream(sInputFilename,
FileMode.Open,
FileAccess.Read);
//Create a DES decryptor from the DES instance.
ICryptoTransform desdecrypt = DES.CreateDecryptor();
//Create crypto stream set to read and do a
//DES decryption transform on incoming bytes.
CryptoStream cryptostreamDecr = new CryptoStream(fsread,
desdecrypt,
CryptoStreamMode.Read);
//Print the contents of the decrypted file.
StreamWriter fsDecrypted = new StreamWriter(sOutputFilename);
fsDecrypted.Write(new StreamReader(cryptostreamDecr).ReadToEnd());
fsDecrypted.Flush();
fsDecrypted.Close();
}
static void Main()
{
// Must be 64 bits, 8 bytes.
// Distribute this key to the user who will decrypt this file.
string sSecretKey;
// Get the Key for the file to Encrypt.
sSecretKey = GenerateKey();
// For additional security Pin the key.
GCHandle gch = GCHandle.Alloc( sSecretKey,GCHandleType.Pinned );
// Encrypt the file.
EncryptFile(@"C:\MyData.txt",
@"C:\Encrypted.txt",
sSecretKey);
// Decrypt the file.
DecryptFile(@"C:\Encrypted.txt",
@"C:\Decrypted.txt",
sSecretKey);
// Remove the Key from memory.
ZeroMemory(gch.AddrOfPinnedObject(), sSecretKey.Length * 2);
gch.Free();
}
}
}