net文本加密
.Net軟體的特點,一些強大的編譯工具可以對.Net可執行文件進行反編譯操作,並得出相應的IL代碼甚至是源代碼。即使是採用混淆工具以及強命名工具也不能從根本上解決問題,代碼依然會很容易地被Reflectoer等工具反編譯源代碼。
軟體加密狗:威步(WIBU)的CodeMeter,AxProtector(for.net)兩款軟體加密狗性能非常不錯
反編譯的問題,與傳統的代碼混淆工具(Obfuscator)不同,AxProtector可以完全阻止對.NET
程序集(由
C#,
VB.NET,
Delphi.NET,
ASP.Net…
等語言編寫)的反編譯。通俗的講,AxProtector在破解者和您的
.NET
代碼之間構建了強大的防破解保護屏障,生成一個基於
Windows
的而不是基於
MSIL
的兼容格式文件。原始的
.NET
代碼完整的被加密後封裝在本地代碼內,無論何時都不會釋放到硬碟,對於破解者是不可見的。
與單純的.net加密軟體不同,AxProtector與CodeMeter硬體加密狗配套餐使用,採用了更為嚴密的密鑰管理,及最先進的AES、RSA、ECC等加密演算法存儲或傳輸密鑰,保證通訊安全。
.Net代碼編譯後生成的
.class
中包含有源代碼中的所有信息(不包括注釋),尤其是在其中保存有調試信息的時候。所以一個按照正常方式編譯的.class
文件可以非常輕易地被反編譯。一般軟體開發商會採用一種叫做混淆器的工具。混淆器的作用是對編譯好的代碼進行混淆,使得其無法被反編譯或者反編譯後的代碼混亂難懂。由於混淆器只是混淆了方法名稱或流程,而不能防止源代碼被反編譯,因此混淆器的作用只是增加了反編譯的難度,最終的結果也是治標不治本。對於一些掌握工具的人來說幾乎還是透明的。AxProtector是一款真正意義的加密源代碼、防止反編譯的.net軟體加密軟體。
AxProtector加密了.net原代碼,任何時候原代碼都不可能被還原到硬碟當中。採用AxProtector加密後的.net代碼只有在程序調用或執行某一段函數的時候,才能通過AxProtectorClass在內存中解密後返回到程序中執行,運行之後迅速立即加密。這種隨機加密、按需解密原代碼的功能,能很好的防止.Net程序的反編譯,同時能夠很好地防止API加密點被摘除。有效地保證了源代碼的執行效率和安全性。
2. 使用.net內置的DES進行加密
好了,明白了它的License種類,我們得看看它是如何驗證合法的License的,換句話說就是它的License是如何構成的。它通過定位/bin目錄下的License文件,License文件由類名(FreeTextBox)+ 「.lic」構成。FreeTextBox.Lic文件內容分三個部分,第一部分為明文FreeTextBox License,也就是類名+ License」字元串,第二部分為[License種類的加密文本],加密演算法採用的.NET內置的DES,用於DES加密的密鑰和偏移量均為{ 0x39, 0x48, 0x42, 50, 0x38, 0x31, 70, 0x36 },當然它不是直接對文本加密的,做了一個小小的處理,這個處理就是加上原文本的長度,並預留5位,不夠則補零,例如字元串DistributionLicense,那用於加密的就是00019DistributionLicense,因為字元串DistributionLicense的長度是19位,前面還有3個空位就補3個零。這樣加密後的結果就是=,注意需要用[]分隔,FreeTextBox設計者出於方便使用正則匹配所以使用[]來分隔,第三部分就是你注冊標識的加密文本,當然也有[],處理方式跟第二部分的一樣,例如我的域名為Ycweb.Net,我想以此作為標識來生成License,於是對字元串00009Ycweb.Net進行DES加密,結果為tyn3Gf1Y5GH2VphAJ2U++g==,所以綜合這個三個部分的內容,就構成了一個完整的License文件內容,整理一下就是: FreeTextBox License [=] [tyn3Gf1Y5GH2VphAJ2U++g==] 這是Distribution的License,如果是Professional的License,內容就是: FreeTextBox License [tyn3Gf1Y5GH2VphAJ2U++g==] 補充: 我現在是要加密的方法,求一個函數,將原文:00019DistributionLicense,加密為密文:=],不知所謂,連內容都不看就回答了 補充: 又多一個不看內容的,文章裡面不是說了嗎:
3. 用.net實現文件夾加密
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO ;
using System.Diagnostics ;
using System.Threading ;
namespace 偽裝文件夾
{
/// <summary>
/// Form1 的摘要說明。
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.FolderBrowserDialog foldeOpen;
private System.Windows.Forms.TextBox AfoldePath;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Button button3;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.Button AddPassword;
private System.Windows.Forms.ComboBox comboBox1;
private System.ComponentModel.IContainer components;
public Form1()
{
//
// Windows 窗體設計器支持所必需的
//
InitializeComponent();
//
// TODO: 在 InitializeComponent 調用後添加任何構造函數代碼
//
}
/// <summary>
/// 清理所有正在使用的資源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows 窗體設計器生成的代碼
/// <summary>
/// 設計器支持所需的方法 - 不要使用代碼編輯器修改
/// 此方法的內容。
/// </summary>
private void InitializeComponent()
{
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Form1));
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.comboBox1 = new System.Windows.Forms.ComboBox();
this.AddPassword = new System.Windows.Forms.Button();
this.button1 = new System.Windows.Forms.Button();
this.AfoldePath = new System.Windows.Forms.TextBox();
this.foldeOpen = new System.Windows.Forms.FolderBrowserDialog();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.button2 = new System.Windows.Forms.Button();
this.button3 = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.groupBox1.SuspendLayout();
this.groupBox2.SuspendLayout();
this.SuspendLayout();
//
// groupBox1
//
this.groupBox1.BackColor = System.Drawing.Color.Transparent;
this.groupBox1.Controls.Add(this.comboBox1);
this.groupBox1.Controls.Add(this.AddPassword);
this.groupBox1.Controls.Add(this.button1);
this.groupBox1.Controls.Add(this.AfoldePath);
this.groupBox1.Location = new System.Drawing.Point(6, 6);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(276, 78);
this.groupBox1.TabIndex = 0;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "加密";
//
// comboBox1
//
this.comboBox1.Items.AddRange(new object[] {
"我的電腦",
"我的文檔",
"撥號網路",
"控制面板",
"計劃任務",
"列印機",
"記事本",
"網路鄰居",
"回收站",
"公文包",
"字體 ",
"Web 文件夾"});
this.comboBox1.Location = new System.Drawing.Point(12, 48);
this.comboBox1.Name = "comboBox1";
this.comboBox1.Size = new System.Drawing.Size(174, 20);
this.comboBox1.TabIndex = 15;
this.comboBox1.Text = "偽裝類型";
//
// AddPassword
//
this.AddPassword.BackColor = System.Drawing.Color.Transparent;
this.AddPassword.ForeColor = System.Drawing.Color.Red;
this.AddPassword.Location = new System.Drawing.Point(192, 48);
this.AddPassword.Name = "AddPassword";
this.AddPassword.TabIndex = 14;
this.AddPassword.Text = "偽裝";
this.AddPassword.Click += new System.EventHandler(this.AddPassword_Click);
//
// button1
//
this.button1.Location = new System.Drawing.Point(192, 20);
this.button1.Name = "button1";
this.button1.TabIndex = 8;
this.button1.Text = "文件夾路徑";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// AfoldePath
//
this.AfoldePath.BackColor = System.Drawing.Color.FromArgb(((System.Byte)(255)), ((System.Byte)(224)), ((System.Byte)(192)));
this.AfoldePath.Location = new System.Drawing.Point(12, 20);
this.AfoldePath.Name = "AfoldePath";
this.AfoldePath.ReadOnly = true;
this.AfoldePath.Size = new System.Drawing.Size(174, 21);
this.AfoldePath.TabIndex = 7;
this.AfoldePath.Text = "";
//
// groupBox2
//
this.groupBox2.BackColor = System.Drawing.Color.Transparent;
this.groupBox2.Controls.Add(this.button2);
this.groupBox2.Controls.Add(this.button3);
this.groupBox2.Controls.Add(this.textBox1);
this.groupBox2.Location = new System.Drawing.Point(6, 90);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(276, 76);
this.groupBox2.TabIndex = 1;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "解密";
//
// button2
//
this.button2.ForeColor = System.Drawing.Color.Red;
this.button2.Location = new System.Drawing.Point(192, 48);
this.button2.Name = "button2";
this.button2.TabIndex = 14;
this.button2.Text = "解密";
this.button2.Click += new System.EventHandler(this.button2_Click);
//
// button3
//
this.button3.ForeColor = System.Drawing.Color.Red;
this.button3.Location = new System.Drawing.Point(192, 20);
this.button3.Name = "button3";
this.button3.TabIndex = 8;
this.button3.Text = "文件夾路徑";
this.button3.Click += new System.EventHandler(this.button3_Click);
//
// textBox1
//
this.textBox1.BackColor = System.Drawing.Color.FromArgb(((System.Byte)(128)), ((System.Byte)(255)), ((System.Byte)(128)));
this.textBox1.Location = new System.Drawing.Point(12, 24);
this.textBox1.Name = "textBox1";
this.textBox1.ReadOnly = true;
this.textBox1.Size = new System.Drawing.Size(174, 21);
this.textBox1.TabIndex = 7;
this.textBox1.Text = "";
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(288, 174);
this.Controls.Add(this.groupBox2);
this.Controls.Add(this.groupBox1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.Name = "Form1";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "偽裝文件夾";
this.groupBox1.ResumeLayout(false);
this.groupBox2.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// 應用程序的主入口點。
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void button1_Click(object sender, System.EventArgs e)
{
if(foldeOpen.ShowDialog ()==DialogResult.OK )
{
try
{
if(foldeOpen.SelectedPath .Substring (3,10)=="Documents ")
{
MessageBox.Show ("我不建議C盤下的文件夾偽裝,這樣可能會導致系統出問題");
}
else
{
AfoldePath.Text =foldeOpen.SelectedPath;
}
}
catch
{
if(foldeOpen.SelectedPath.Length >=4)
{
AfoldePath.Text =foldeOpen.SelectedPath;
}
else
{
MessageBox.Show ("無法對盤符進行偽裝.");
}
}
}
}
private void AddPassword_Click(object sender, System.EventArgs e)
{
try
{
ProcessStartInfo p3=new ProcessStartInfo ("attrib.exe",@"-s -r -a -h "+AfoldePath.Text);
p3.WindowStyle= System.Diagnostics.ProcessWindowStyle.Hidden;
Process.Start (p3);
ProcessStartInfo p1=new ProcessStartInfo ("attrib.exe",@"-s -r -a -h "+AfoldePath.Text+@"\desktop.ini");
p1.WindowStyle= System.Diagnostics.ProcessWindowStyle.Hidden;
Process.Start (p1);
StreamWriter sw2=new StreamWriter (AfoldePath.Text+@"\desktop.ini" );
sw2.WriteLine (@"[.ShellClassInfo]" );
sw2.WriteLine ("CLSID="+GetPasType());
sw2.Close ();
ProcessStartInfo p =new ProcessStartInfo ("attrib.exe",@"+s +a +h +r "+AfoldePath.Text+@"\desktop.ini");
p.WindowStyle= System.Diagnostics.ProcessWindowStyle.Hidden;
Process.Start (p);
ProcessStartInfo p2=new ProcessStartInfo ("attrib.exe",@"+s +r "+AfoldePath.Text);
p2.WindowStyle= System.Diagnostics.ProcessWindowStyle.Hidden;
Process.Start (p2);
}
catch(Exception ee)
{
MessageBox.Show (ee.Message .ToString ());
}
}
private string GetPasType()
{
int index=comboBox1.SelectedIndex;
switch (index)
{
case 0: return @"{20D04FE0-3AEA-1069-A2D8-08002B30309D}";
case 1: return @"{450D8FBA-AD25-11D0-98A8-0800361B1103}";
case 2: return @"{992CFFA0-F557-101A-88EC-00DD010CCC48}";
case 3: return @"{21EC2020-3AEA-1069-A2DD-08002B30309D}";
case 4: return @"{D6277990-4C6A-11CF-8D87-00AA0060F5BF}";
case 5: return @"{2227A280-3AEA-1069-A2DE-08002B30309D}";
case 6: return @"{1FBA04EE-3024-11D2-8F1F-0000F87ABD16}";
case 7: return @"{208D2C60-3AEA-1069-A2D7-08002B30309D}";
case 8: return @"{645FF040-5081-101B-9F08-00AA002F954E}";
case 9: return @"{85BBD920-42A0-1069-A2E4-08002B30309D}";
case 10: return @"{BD84B380-8CA2-1069-AB1D-08000948F534}";
case 11: return @"{BDEADF00-C265-11d0-BCED-00A0C90AB50F}";
}
return @"{20D04FE0-3AEA-1069-A2D8-08002B30309D}";
}
private void button3_Click(object sender, System.EventArgs e)
{
if(foldeOpen.ShowDialog ()==DialogResult.OK )
{
textBox1.Text =foldeOpen.SelectedPath;
}
}
private void button2_Click(object sender, System.EventArgs e)
{
try
{
ProcessStartInfo p2=new ProcessStartInfo ("attrib.exe",@"-s -r -a -h "+textBox1.Text);
p2.WindowStyle= System.Diagnostics.ProcessWindowStyle.Hidden;
Process.Start (p2);
ProcessStartInfo p1=new ProcessStartInfo ("attrib.exe",@"-s -h -r "+textBox1.Text+@"\desktop.ini");
p1.WindowStyle= System.Diagnostics.ProcessWindowStyle.Hidden;
Process.Start (p1);
System.Threading.Thread.Sleep(1000);
File.Delete (textBox1.Text+@"\desktop.ini");
MessageBox.Show ("解密成功.");
}
catch(Exception ee)
{
MessageBox.Show (ee.Message.ToString ());
}
}
}
}
4. .NET中的密碼學--對稱加密
介紹
在 net之前 使用非託管的Win APIs加密解密數據是一件非常痛苦的事情 為了這個加密解密的目的 NET配置了一組類(和命名空間) 現在你有很多類可以使用每種不同的演算法保護你的數據 在 NET裡面Crypttography命名空間下又定義了 種類型的加密方法 他們是AsymmetricAlgorithm SymmetricAlgorithm和HashAlgorithm 所有的這些類(和 NET密碼學類型)都是抽象類 我們今天將要描述SymmetricAlgorithm 剩下的將在以後的文章中陸續講解
注意 雖然大多數託管代碼里的加密類實現使用了很多CryptoAPI庫
SymmetricAlgorithms基礎
對稱演算法使用用戶的密鑰(密碼)工作 它的意思是 任何時候你都可以實現它而且可以使用對稱演算法加密或者解密你的數據 為了加密或者解密你的數據你必須定義一個密碼或者一個密鑰 下面描述了對稱加密的特性
加密的強度依賴於你的密鑰(密碼) 如果你配置一個長的密鑰 它將是非常難破解的 意思是他將要花費很長的時間讓黑客找到密鑰
對稱加密的一個風險是密碼應該讓第二個人知道(這個人必須用你的密鑰來解密數據)
這種加密演算法是基於簡單的數學操作 因此它工作的非常快 因此當你要加密的數據量非常大的時候它是最好的選擇
基於對稱的加密可以被黑客暴力破解 但是如果你定義一個非常好的密碼(足夠長) 這個破解的過程將需要很長的時間
一旦用戶定義了密鑰 黑客可以使用暴力破解或者字典來編碼或者解密你的信息 但是長的密鑰可以在黑客破解你的密碼的時候保護你的數據更長的時間
另外在使用密鑰或者密碼對稱加密過程中有一件非常重要的事情 就是初始化向量(IV) IV被使用在最初的編碼中(加密或者解密) 在所有的對稱演算法類中我們有一個名叫Mode的屬性 這是被IV使用的 如果我們設置Mode屬性為CipherMode CBC(Cipher Block Chaining) 則使用這個模式 每個數據塊使用來自前一個塊的值來處理 意思是如果系統在處理第三塊數據 則它會從第二塊中取一些信息(處理第三塊數據) 接著它會取第一塊數據中的信息用來處理第二塊數據 但是在第一塊數據之前沒有可以用的塊 因此它將使用IV來處理第一塊 這個技術確保沒有兩個相同的塊產生相同的輸出並且因此使得數據更安全 然而如果你使Mode=CipherModer ECB(Electronic codebook mode) 則他不會使用上面的方法(使用前面的處理的塊信息處理後面的塊) 如果你想用很少的資源和時間處理大量的消息那麼這個方法對於你來說就很有用 他也可以讓你從數據的中間開始處理
應此 上面我們包含了在對稱加密中的兩間非常重要的事情 他們是密鑰和初始化向量 現在讓我們看看對稱加密支持哪些演算法
對稱演算法和對稱演算法類
下面是對稱演算法和他們的類的關鍵信息
演算法名稱演算法類(抽象)有效密鑰大小(Bit)默認密鑰大小(Bit)默認實現類
DESDES DESCryptoServiceProvider
TripleDESTripleDES
RC RC RC CryptoServiceProvider
RijnDaelRijnDael RijnDaelManaged
這里需要注意的是所有的演算法類都是繼承於抽象類SymmetricAlgorithm 並且你可以看到每個類都支持不同的密鑰大小 相同的情況下 他們也支持不同的初始化向量的大小 正如我剛才所說的他們所有的類都是抽象類 因此我們不能直接創建這些抽象類的任何實例 但是SymmetricAlgorithm類(也是抽象類)有一個共享的方法叫Create可以不用操心它是如何實現來創建一個類的具體實例 意思是 你可以通過下面的方式使用它
RC mRC = RC Create()
它將為您返回一個RC 默認實現的一個實例 而不用去關心具體如何實現RC 這個類 如果你想在微軟以後更新RC 類的實現還能共享代碼(成為可能) 這個技術是非常有用的 在那種情況下 你的代碼將自動適應它們的改變並且正確的工作 或者可能在將來RC 類用託管代碼寫 你的代碼依然可以接受它 在相同的情況下 你同樣可以使用下面的語句
RC mCrypto = SymmetricAlgorithm Create( RC )
這也可以給你返回一個RC 的對象(默認實現) 在這種情況下你要使用重裁Create方法用演算法的名字設置參數來返回演算法的對象 這個Create方法來自SymmetricAlgorithm類 並且向我前面說的所有的使用對稱演算法的其它類都繼承於SymmetricAlgorithm 因此你可以在上面所有的類裡面找到Create這個方法 意思是如果你使用RC Create( DES )則它也能工作並且將返回一個DES的對象 但是不能使用RC 類得到DES對象
上面的機制看起來很有用 我們可以用同樣的方法使用我們自己的演算法定義自己的類 但是要想這樣 我們必須要對nfig文件作一些小的改動 我在這里不詳細描述 你可以參考Wrox關於密碼學的書得到更多的信息
現在讓我們看看SymmetricAlgorithm類裡面的一些方法和屬性
BlockSize 分開處理的數據塊的大小 大的數據將被分成小的數據塊來處理 如果數據小於塊大小 則被追加(使用一些默認值填充)
Key 在處理數據的時候將要使用密鑰 這個密鑰被配置成使用位元組數組
IV 數據處理的時候使用初始化向量(上面已經描述) 配置成位元組數組
KeySize 密鑰的所有位的大小
LegalBlockSize 返回BlockSize的枚舉告訴你判斷包括最大值 最小值和跳躍值在內的塊的大小 跳躍值意思是還有多少值應該添加判斷值得到下一個值 比如如果最小值是 跳躍值是 那麼下一個判斷值就是 等等 (Returns the BlockSize Enumeration which tells you legal values for block size including max value min value and Skip value Skip value means that how much value should be added to last legal value to get next value Like if min value is and Skipvalue is it means next legal values will be and so on )
Mode 位操作得到或者設置模式 見上面描述 值是CipherMode枚舉中的一個
Padding 得到或者設置PaddingMode枚舉中的一個追加值 (填充塊中空餘的區域)
LegalKeySize 和LegalBlockSize一樣 但是處理的是KeySize
Create 上面已經描述 使用它創建默認演算法實現的類的實例
CreateEncryptor 返回一個可以手動加密數據的IcryptoTransform對象 一會將仔細描述
CreateDecryptor 返回一個可以手動解密數據的IcryptoTransform對象 一會將仔細描述
GeneratrKey and GenerateIV 在加密或者解密的過程中如果Key和IV是null則這些方法可以產生默認的密鑰和IV
VaildKeySize 檢查給定的密鑰是不是演算法的有效的密鑰
Clear 清除和消除所有的資源以及象密鑰和IV這樣的內存信息
在寫代碼之前 讓我們說幾件對我們理解代碼非常用幫助的事情
CreateEncryptor和CreateDecryptor
SymmetricAlgorithm類的CreateEncryptor和CreateDecryptor方法返回ICryptoTransform對象 IcryptoTransform是一個想要處理數據塊的類來實現的介面 這個過程可以是加密 解密 散列 基於 的編碼和解碼等等 這個介面的基本目的是完成數據處理分塊(The basic purpose of this Interface is to perform Blockwize processing of data ) 你可以直接使用它的實例 但是在大多數情況下 為了方便 我們通過其他的名叫CryptoStream來完成 讓我們看一個例子是如何使用它的
DES mCrypt = new SymmetricAlgorithm Create( DES )
ICryptoTransform mTransform = mCrypt CreateEncryptot()
CreateEncryptor或者CreateDecryptor是兩個重裁的方法 如果你沒有任何參數傳入其中 那麼將使用默認的密鑰和IV(使用SymmetricAlgoruthm類裡面的GenerateKey和GenerateIV方法) 另一方面 你可以通過傳入一個IV和密鑰到CreateEncryptor和CreateDecryptor的對象中 以致加密和解密將使用我們自己定義的IV和密鑰
CryptoStream 類
CryptoStream類通常被使用來讀寫數據同時也在讀或者寫的時候加密或者解密數據 它是簡單的包裝了一下原始流類Stream It uses the buffered Access taking all worries from you to manage buffer block sizes padding etc 你可以使用下面的代碼得到它的實例
DES mCrypt = SymmetricAlgorithm Create( DES )
IcryptoTransform mTransform = mCrypt CreateEncryptor()
CryptoStream mStream = new CryptoStream(fileStream mTransform CryptoStramMode Read)
fileStream是請求從硬碟或者內存中讀取數據的原始文件的流(或者是MemoryStream) 現在通過使用mStream對象和StreamReader/StreamWriter對象讀寫數據 當你將要讀寫時 你的加密解密信息將依賴IcryptoTransform對象
代碼例子
現在我們有足夠關於SymmetricAlgorithm的信息 最後 讓我們看看將要編碼和解碼的代碼片斷 我假設你擁有一個包含txtData和命令按鈕控制項的窗體 在命令按鈕的代碼事件里寫如下代碼 這個代碼將要加密TextBox裡面的文本並用MessageBox顯示 在將加密結果寫回到TextBox中
SymmetricAlgorithm mCryptProv
MemoryStream mMemStr
// 加密txtData中的數據 然後將加密結果用MessageBox顯示並且回寫到TextBox中
// 這里你可以配置任何 net支持的類
DES mCryptProv = SymmetricAlgorithm Create( Rijndael )
// 加密數據將要以流的形式存儲在內存中因此我們需要內存Stream對象
mMemStr = new MemoryStream()
// 創建ICryptTransform對象 (在這里我們使用默認的密鑰和初始向量)
ICryptTramsform mTransform = mCryptProv CreateEncryptor()
CryptoStream mCSWriter = new CryptoStream(mMemStr mTransform CryptoStreamMode Write)
StreamWriter mSWriter = StreamWriter(mCSWriter)
mSwriter Writer(this txtData Text)
mSWriter Flush()
mCSWriter FlushFinalBlock()
有一件事情在這里需要注意我們沒有在代碼的任何地方使用IV和密鑰 事實上 在我們在代碼裡面沒有指定他們的時候 NET Framework將為我們自動產生 但是本文包含的例子代碼使用的是用戶指定的密鑰和IV 我們將加密以後的數據使用MemoryStream寫到內存中 現在讓我們從內存中得到數據的代碼
// 數據已經寫入內存但是我們需要回顯它到TextBox和MessageBox中 因此要做下面的工作
// 為接受數據創建位元組數組
byte[] mBytes = new byte[mMemStr Length ]
mMemStr Position =
mMemStr Read(mBytes mMemStr Length)
Text UTF Encoding mEnc = new Text UTF Encoding()
String mEncData = mEnc GetString(mBytes)
MessageBox Show( 加密數據為 +mEncData)
This txtData Text = mEncData
從位元組轉換為字元串必須要編碼 在這里我使用了UTF Encoding 最後 讓我們將解密後的數據再次顯示在MessageBox和TextBox中
// 現在讓我們從內存中得到解密後的數據
// 因為我們的數據在內存中 所以我們需要重新使用MemoryStream對象
// 將內存點置
mMemStr Position =
mTransform = mCryptProv CreateDecryptor()
CryptoStream mCSReader = new CryptoStream(mMemStr mTransform CryptoStreamMode Read)
StreamReader mStrReader = new StreamReader(mCSReader)
String mDecData = mStrReader ReadToEnd()
MessageBox( 解密數據為 +mDecData)
This txtData Text = mDecData
這是所有的工作 解密那些數據我們使用了相同的內存流 為了能從流的其實部分讀數據我們首先將它置為開始 然後我們用SymmetricAlgorithm對象的CreateDecryptor方法創建IcryptoTransform對象 我們在上面的代碼中為了解密重復使用了對象(mMemStr) 你可以創建新的對象(使用新的變數) 然後我們為了從內存中讀取數據需要StreamReader對象 While reading that it will also decrypt that data since we passed CryptoStream object ring the creation of StreamReader object
最後的話
NET為我們提供了一個非常好的託管途徑保護我們的數據 我們可以使用 NET內建的一組類來加密我們的數據 雖然很多的類後台依然使用Crypto APIs技術 我們使用老的Crypto APIs沒有任何問題 但是我們可以不用擔心那些類的具體實現來安全的使用這些類 在後面的文章我將描述非對稱加密演算法的神話和用途
關於例子
lishixin/Article/program/net/201311/13972