RC2加密算法在C#的應(yīng)用----完善版 .Net教程-C#語(yǔ)言
using System; using System.Security.Cryptography; using System.Text; using System.IO; using System.Windows.Forms;
namespace Curllion { public class Crypt { private byte[] key; private byte[] iv; private System.Text.ASCIIEncoding asciiEncoding; private System.Text.UnicodeEncoding textConverter; private RC2CryptoServiceProvider rc2CSP; public Crypt() { InitializeComponent(); } private void InitializeComponent() { key = new byte[]{106,51,25,141,157,142,23,111,234,159,187,154,215,34,37,204}; iv = new byte[]{135,186,133,136,184,149,153,144}; asciiEncoding = new System.Text.ASCIIEncoding(); textConverter = new System.Text.UnicodeEncoding(); rc2CSP = new RC2CryptoServiceProvider(); } /// <summary> /// 新建一個(gè)大小為10261B的文件,以便將加密數(shù)據(jù)寫(xiě)入固定大小的文件。 /// </summary> /// <param name="filePath">文件保存的地址,包含文件名</param> public void InitBinFile(string filePath) { byte[] tmp = new byte[10261]; try //創(chuàng)建文件流,將其內(nèi)容全部寫(xiě)入0 { System.IO.FileStream writeFileStream = new FileStream(filePath, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None,512,false);
for(int i = 0 ;i< 10261;i++) tmp[i] = 0; writeFileStream.Write(tmp,0,10261); writeFileStream.Flush(); writeFileStream.Close(); } catch(System.IO.IOException) { MessageBox.Show("文件操作錯(cuò)誤!","錯(cuò)誤!",MessageBoxButtons.OK,MessageBoxIcon.Error); } } /// <summary> /// 將文本數(shù)據(jù)加密后寫(xiě)入一個(gè)文件,其中,這個(gè)文件是用InitBinFile建立的,這個(gè)文件將被分成十塊, /// 用來(lái)分別保存10組不同的數(shù)據(jù),第一個(gè)byte位保留,第2位到第21位分別用來(lái)存放每塊數(shù)據(jù)的長(zhǎng)度,但 /// 一個(gè)byte的取值為0-127,所以,用兩個(gè)byte來(lái)存放一個(gè)長(zhǎng)度。 /// </summary> /// <param name="toEncryptText">要加密的文本數(shù)據(jù)</param> /// <param name="filePath">要寫(xiě)入的文件</param> /// <param name="dataIndex">寫(xiě)入第幾塊,取值為1--10</param> /// <returns>是否操作成功</returns> public bool EncryptToFile(string toEncryptText,string filePath,int dataIndex) { bool r = false; if(dataIndex > 10 && dataIndex < 1) { MessageBox.Show("數(shù)據(jù)索引的取值范圍在1至10之間!","錯(cuò)誤!", MessageBoxButtons.OK,MessageBoxIcon.Error); return r; } byte[] encrypted; //打開(kāi)要寫(xiě)入的文件,主要是為了保持原文件的內(nèi)容不丟失 System.IO.FileStream tmpFileStream= new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.None,1024,true);
byte[] index = new byte[10261]; //將讀取的內(nèi)容寫(xiě)到byte數(shù)組 tmpFileStream.Read(index,0,10261); tmpFileStream.Close(); //定義基本的加密轉(zhuǎn)換運(yùn)算 System.Security.Cryptography.ICryptoTransform Encryptor = rc2CSP.CreateEncryptor(this.key,this.iv); System.IO.MemoryStream msEncrypt = new MemoryStream(); //在此加密轉(zhuǎn)換流中,加密將從csEncrypt,加密后,結(jié)果在msEncrypt流中。 System.Security.Cryptography.CryptoStream csEncrypt = new CryptoStream(msEncrypt, Encryptor,CryptoStreamMode.Write); //將要加密的文本轉(zhuǎn)換成UTF-16 編碼,保存在tmp數(shù)組。 byte[] tmp = textConverter.GetBytes(toEncryptText); //將tmp輸入csEncrypt,將通過(guò)Encryptor來(lái)加密。 csEncrypt.Write(tmp,0,tmp.Length); //輸出到msEnctypt csEncrypt.FlushFinalBlock(); //將流轉(zhuǎn)成byte[] encrypted = msEncrypt.ToArray(); if(encrypted.Length>1024) { MessageBox.Show("加密后,數(shù)據(jù)長(zhǎng)度大于1KB,無(wú)法保存"); return false; } //得到加密后數(shù)據(jù)的大小,將結(jié)果存在指定的位置。 index[dataIndex*2 - 1] = Convert.ToByte(Convert.ToString(encrypted.Length/128)); index[dataIndex*2] = Convert.ToByte(Convert.ToString(encrypted.Length%128)); //將加密后的結(jié)果寫(xiě)入index(覆蓋) for(int i=0;i<encrypted.Length;i++) index[1024*(dataIndex-1)+21+i]=encrypted[i]; //建立文件流 tmpFileStream = new FileStream(filePath, System.IO.FileMode.Truncate, System.IO.FileAccess.Write, System.IO.FileShare.None,1024,true); //寫(xiě)文件 tmpFileStream.Write(index,0,10261); tmpFileStream.Flush(); r = true; tmpFileStream.Close(); return r; } /// <summary> /// 從一個(gè)文件中解密出一段文本,其中,這個(gè)文件是由InitBinFile建立的,并且由 EncryptToFile加密的 /// </summary> /// <param name="filePath">要解密的文件</param> /// <param name="dataIndex">要從哪一個(gè)塊中解密</param> /// <returns>解密后的文本</returns> public string DecryptFromFile(string filePath,int dataIndex) { string r = ""; if(dataIndex > 10 && dataIndex < 1) { MessageBox.Show("數(shù)據(jù)索引的取值范圍在1至10之間!","錯(cuò)誤!", MessageBoxButtons.OK,MessageBoxIcon.Error); return r; } byte[] decrypted; System.IO.FileStream tmpFileStream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.None,1024,true);
System.Security.Cryptography.ICryptoTransform Decryptor = rc2CSP.CreateDecryptor(this.key,this.iv); System.IO.MemoryStream msDecrypt = new MemoryStream(); System.Security.Cryptography.CryptoStream csDecrypt = new CryptoStream(msDecrypt, Decryptor,CryptoStreamMode.Write); byte[] index = new byte[10261];
tmpFileStream.Read(index,0,10261); int startIndex = 1024*(dataIndex-1)+21; int count = index[dataIndex*2 - 1]*128 + index[dataIndex*2]; byte[] tmp = new byte[count];
Array.Copy(index,1024*(dataIndex-1)+21,tmp,0,count); csDecrypt.Write(tmp,0,count); csDecrypt.FlushFinalBlock(); decrypted = msDecrypt.ToArray(); r = textConverter.GetString(decrypted,0,decrypted.Length); tmpFileStream.Close(); return r; } /// <summary> /// 將一段文本加密后保存到一個(gè)文件 /// </summary> /// <param name="toEncryptText">要加密的文本數(shù)據(jù)</param> /// <param name="filePath">要保存的文件</param> /// <returns>是否加密成功</returns> public bool EncryptToFile(string toEncryptText,string filePath) { bool r = false; byte[] encrypted; System.IO.FileStream tmpFileStream = new FileStream(filePath, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write, System.IO.FileShare.None,1024,true);
System.Security.Cryptography.ICryptoTransform Encryptor = rc2CSP.CreateEncryptor(this.key,this.iv); System.IO.MemoryStream msEncrypt = new MemoryStream(); System.Security.Cryptography.CryptoStream csEncrypt = new CryptoStream(msEncrypt, Encryptor,CryptoStreamMode.Write);
byte[] tmp = textConverter.GetBytes(toEncryptText); csEncrypt.Write(tmp,0,tmp.Length); csEncrypt.FlushFinalBlock(); encrypted = msEncrypt.ToArray(); tmpFileStream.Write(encrypted,0,encrypted.Length); tmpFileStream.Flush(); r = true; tmpFileStream.Close(); return r; } /// <summary> /// 將一個(gè)被加密的文件解密 /// </summary> /// <param name="filePath">要解密的文件</param> /// <returns>解密后的文本</returns> public string DecryptFromFile(string filePath) { string r = ""; byte[] decrypted; System.IO.FileStream tmpFileStream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.None,1024,true); System.Security.Cryptography.ICryptoTransform Decryptor = rc2CSP.CreateDecryptor(this.key,this.iv); System.IO.MemoryStream msDecrypt = new MemoryStream(); System.Security.Cryptography.CryptoStream csDecrypt = new CryptoStream(msDecrypt, Decryptor,CryptoStreamMode.Write);
byte[] tmp = new byte[tmpFileStream.Length]; tmpFileStream.Read(tmp,0,tmp.Length); csDecrypt.Write(tmp,0,tmp.Length); csDecrypt.FlushFinalBlock(); decrypted = msDecrypt.ToArray(); r = textConverter.GetString(decrypted,0,decrypted.Length); tmpFileStream.Close(); return r; } //------------------------------------------------------------- /// <summary> /// 將文本數(shù)據(jù)加密后寫(xiě)入一個(gè)文件,其中,這個(gè)文件是用InitBinFile建立的,這個(gè)文件將被分成十塊, /// 用來(lái)分別保存10組不同的數(shù)據(jù),第一個(gè)byte位保留,第2位到第21位分別用來(lái)存放每塊數(shù)據(jù)的長(zhǎng)度,但 /// 一個(gè)byte的取值為0-127,所以,用兩個(gè)byte來(lái)存放一個(gè)長(zhǎng)度。 /// </summary> /// <param name="toEncryptText">要加密的文本數(shù)據(jù)</param> /// <param name="filePath">要寫(xiě)入的文件</param> /// <param name="dataIndex">寫(xiě)入第幾塊,取值為1--10</param> /// <param name="IV">初始化向量</param> /// <param name="Key">加密密匙</param> /// <returns>是否操作成功</returns> public bool EncryptToFile(string toEncryptText,string filePath,int dataIndex,byte[] IV,byte[] Key) { bool r = false; if(dataIndex > 10 && dataIndex < 1) { MessageBox.Show("數(shù)據(jù)索引的取值范圍在1至10之間!","錯(cuò)誤!", MessageBoxButtons.OK,MessageBoxIcon.Error); return r; } byte[] encrypted; //打開(kāi)要寫(xiě)入的文件,主要是為了保持原文件的內(nèi)容不丟失 System.IO.FileStream tmpFileStream= new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.None,1024,true);
byte[] index = new byte[10261]; //將讀取的內(nèi)容寫(xiě)到byte數(shù)組 tmpFileStream.Read(index,0,10261); tmpFileStream.Close(); //定義基本的加密轉(zhuǎn)換運(yùn)算 System.Security.Cryptography.ICryptoTransform Encryptor = rc2CSP.CreateEncryptor(Key,IV); System.IO.MemoryStream msEncrypt = new MemoryStream(); //在此加密轉(zhuǎn)換流中,加密將從csEncrypt,加密后,結(jié)果在msEncrypt流中。 System.Security.Cryptography.CryptoStream csEncrypt = new CryptoStream(msEncrypt, Encryptor,CryptoStreamMode.Write); //將要加密的文本轉(zhuǎn)換成UTF-16 編碼,保存在tmp數(shù)組。 byte[] tmp = textConverter.GetBytes(toEncryptText); //將tmp輸入csEncrypt,將通過(guò)Encryptor來(lái)加密。 csEncrypt.Write(tmp,0,tmp.Length); //輸出到msEnctypt csEncrypt.FlushFinalBlock(); //將流轉(zhuǎn)成byte[] encrypted = msEncrypt.ToArray(); if(encrypted.Length>1024) { MessageBox.Show("加密后,數(shù)據(jù)長(zhǎng)度大于1KB,無(wú)法保存"); return false; } //得到加密后數(shù)據(jù)的大小,將結(jié)果存在指定的位置。 index[dataIndex*2 - 1] = Convert.ToByte(Convert.ToString(encrypted.Length/128)); index[dataIndex*2] = Convert.ToByte(Convert.ToString(encrypted.Length%128)); //將加密后的結(jié)果寫(xiě)入index(覆蓋) for(int i=0;i<encrypted.Length;i++) index[1024*(dataIndex-1)+21+i]=encrypted[i]; //建立文件流 tmpFileStream = new FileStream(filePath, System.IO.FileMode.Truncate, System.IO.FileAccess.Write, System.IO.FileShare.None,1024,true); //寫(xiě)文件 tmpFileStream.Write(index,0,10261); tmpFileStream.Flush(); r = true; tmpFileStream.Close(); return r; } /// <summary> /// 從一個(gè)文件中解密出一段文本,其中,這個(gè)文件是由InitBinFile建立的,并且由 EncryptToFile加密的 /// </summary> /// <param name="filePath">要解密的文件</param> /// <param name="dataIndex">要從哪一個(gè)塊中解密</param> /// <param name="IV">初始化向量</param> /// <param name="Key">解密密匙</param> /// <returns>解密后的文本</returns> public string DecryptFromFile(string filePath,int dataIndex,byte[] IV,byte[] Key) { string r = ""; if(dataIndex > 10 && dataIndex < 1) { MessageBox.Show("數(shù)據(jù)索引的取值范圍在1至10之間!","錯(cuò)誤!", MessageBoxButtons.OK,MessageBoxIcon.Error); return r; } byte[] decrypted; System.IO.FileStream tmpFileStream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.None,1024,true);
System.Security.Cryptography.ICryptoTransform Decryptor = rc2CSP.CreateDecryptor(Key,IV); System.IO.MemoryStream msDecrypt = new MemoryStream(); System.Security.Cryptography.CryptoStream csDecrypt = new CryptoStream(msDecrypt, Decryptor,CryptoStreamMode.Write); byte[] index = new byte[10261];
tmpFileStream.Read(index,0,10261); int startIndex = 1024*(dataIndex-1)+21; int count = index[dataIndex*2 - 1]*128 + index[dataIndex*2]; byte[] tmp = new byte[count];
Array.Copy(index,1024*(dataIndex-1)+21,tmp,0,count); csDecrypt.Write(tmp,0,count); csDecrypt.FlushFinalBlock(); decrypted = msDecrypt.ToArray(); r = textConverter.GetString(decrypted,0,decrypted.Length); tmpFileStream.Close(); return r; } /// <summary> /// 將一段文本加密后保存到一個(gè)文件 /// </summary> /// <param name="toEncryptText">要加密的文本數(shù)據(jù)</param> /// <param name="filePath">要保存的文件</param> /// <param name="IV">初始化向量</param> /// <param name="Key">加密密匙</param> /// <returns>是否加密成功</returns> public bool EncryptToFile(string toEncryptText,string filePath,byte[] IV,byte[] Key) { bool r = false; byte[] encrypted; System.IO.FileStream tmpFileStream = new FileStream(filePath, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write, System.IO.FileShare.None,1024,true);
System.Security.Cryptography.ICryptoTransform Encryptor = rc2CSP.CreateEncryptor(Key,IV); System.IO.MemoryStream msEncrypt = new MemoryStream(); System.Security.Cryptography.CryptoStream csEncrypt = new CryptoStream(msEncrypt, Encryptor,CryptoStreamMode.Write);
byte[] tmp = textConverter.GetBytes(toEncryptText); csEncrypt.Write(tmp,0,tmp.Length); csEncrypt.FlushFinalBlock(); encrypted = msEncrypt.ToArray(); tmpFileStream.Write(encrypted,0,encrypted.Length); tmpFileStream.Flush(); r = true; tmpFileStream.Close(); return r; } /// <summary> /// 將一個(gè)被加密的文件解密 /// </summary> /// <param name="filePath">要解密的文件</param> /// <param name="IV">初始化向量</param> /// <param name="Key">解密密匙</param> /// <returns>解密后的文本</returns> public string DecryptFromFile(string filePath,byte[] IV,byte[] Key) { string r = ""; byte[] decrypted; System.IO.FileStream tmpFileStream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.None,1024,true); System.Security.Cryptography.ICryptoTransform Decryptor = rc2CSP.CreateDecryptor(Key,IV); System.IO.MemoryStream msDecrypt = new MemoryStream(); System.Security.Cryptography.CryptoStream csDecrypt = new CryptoStream(msDecrypt, Decryptor,CryptoStreamMode.Write);
byte[] tmp = new byte[tmpFileStream.Length]; tmpFileStream.Read(tmp,0,tmp.Length); csDecrypt.Write(tmp,0,tmp.Length); csDecrypt.FlushFinalBlock(); decrypted = msDecrypt.ToArray(); r = textConverter.GetString(decrypted,0,decrypted.Length); tmpFileStream.Close(); return r; } /// <summary> /// 設(shè)置加密或解密的初始化向量 /// </summary> /// <param name="s">長(zhǎng)度等于8的ASCII字符集的字符串</param> public void SetIV(string s) { if(s.Length != 8) { MessageBox.Show("輸入的字符串必須為長(zhǎng)度為8的且屬于ASCII字符集的字符串"); this.iv =null; return; } try { this.iv = this.asciiEncoding.GetBytes(s); } catch(System.Exception) { MessageBox.Show("輸入的字符串必須為長(zhǎng)度為8的且屬于ASCII字符集的字符串"); this.iv = null; } } /// <summary> /// 設(shè)置加密或解密的密匙 /// </summary> /// <param name="s">長(zhǎng)度等于16的ASCII字符集的字符串</param> public void SetKey(string s) { if(s.Length != 16) { MessageBox.Show("輸入的字符串必須為長(zhǎng)度為16的且屬于ASCII字符集的字符串"); this.key = null; return; } try { this.key = this.asciiEncoding.GetBytes(s); } catch(System.Exception) { MessageBox.Show("輸入的字符串必須為長(zhǎng)度為16的且屬于ASCII字符集的字符串"); this.key = null; } } } }
|