using System;
using System.Security.Cryptography;
using System.Text;
using System.IO;
using System.Windows.Forms;
namespace Curllion
{
public class Crypt
{
/// <summary>
/// 新建一個大小爲10261B的文件,以便將加密數據寫入固定大小的文件。
/// </summary>
/// <param name="filePath">文件保存的地址,包含文件名</param>
public static void InitBinFile(string filePath)
{
byte[] tmp = new byte[10261];
try //創建文件流,將其內容全部寫入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("文件操作錯誤!","錯誤!",MessageBoxButtons.OK,MessageBoxIcon.Error);
}
}
/// <summary>
/// 將文本數據加密後寫入一個文件,其中,這個文件是用InitBinFile建立的,這個文件將被分成十塊,
/// 用來分別保存10組不同的數據,第一個byte位保留,第2位到第21位分別用來存放每塊數據的長度,但
/// 一個byte的取值爲0-127,所以,用兩個byte來存放一個長度。
/// </summary>
/// <param name="toEncryptText">要加密的文本</param>
/// <param name="filePath">要寫入的文件</param>
/// <param name="dataIndex">寫入第幾塊,取值爲1--10</param>
/// <returns>是否操作成功</returns>
public static bool EncryptToFile(string toEncryptText,string filePath,int dataIndex)
{
bool r = false;
if(dataIndex > 10 && dataIndex < 1)
{
MessageBox.Show("數據索引的取值範圍在1至10之間!","錯誤!",
MessageBoxButtons.OK,MessageBoxIcon.Error);
return r;
}
byte[] encrypted;
//初始化向量
byte[] key = {106,51,25,141,157,142,23,111,234,159,187,154,215,34,37,204};
//密匙
byte[] IV = {135,186,133,136,184,149,153,144};
//創建UTF-16 編碼,用來在byte[]和string之間轉換
System.Text.UnicodeEncoding textConverter = new UnicodeEncoding();
//創建RC2服務
RC2CryptoServiceProvider rc2CSP = new RC2CryptoServiceProvider();
//打開要寫入的文件,主要是爲了保持原文件的內容不丟失
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];
//將讀取的內容寫到byte數組
tmpFileStream.Read(index,0,10261);
tmpFileStream.Close();
//定義基本的加密轉換運算
System.Security.Cryptography.ICryptoTransform Encryptor = rc2CSP.CreateEncryptor(key,IV);
System.IO.MemoryStream msEncrypt = new MemoryStream();
//在此加密轉換流中,加密將從csEncrypt,加密後,結果在msEncrypt流中。
System.Security.Cryptography.CryptoStream csEncrypt = new CryptoStream(msEncrypt,
Encryptor,CryptoStreamMode.Write);
//將要加密的文本轉換成UTF-16 編碼,保存在tmp數組。
byte[] tmp = textConverter.GetBytes(toEncryptText);
//將tmp輸入csEncrypt,將通過Encryptor來加密。
csEncrypt.Write(tmp,0,tmp.Length);
//輸出到msEnctypt
csEncrypt.FlushFinalBlock();
//將流轉成byte[]
encrypted = msEncrypt.ToArray();
if(encrypted.Length>1024)
{
MessageBox.Show("加密後,數據長度大於1KB,無法保存");
return false;
}
//得到加密後數據的大小,將結果存在指定的位置。
index[dataIndex*2 - 1] = Convert.ToByte(Convert.ToString(encrypted.Length/128));
index[dataIndex*2] = Convert.ToByte(Convert.ToString(encrypted.Length%128));
//將加密後的結果寫入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);
//寫文件
tmpFileStream.Write(index,0,10261);
tmpFileStream.Flush();
r = true;
tmpFileStream.Close();
return r;
}
/// <summary>
/// 從一個文件中解密出一段文本,其中,這個文件是由InitBinFile建立的,並且由 EncryptToFile加密的
/// </summary>
/// <param name="filePath">要解密的文件</param>
/// <param name="dataIndex">要從哪一個塊中解密</param>
/// <returns>解密後的文本</returns>
public static string DecryptFromFile(string filePath,int dataIndex)
{
string r = "";
if(dataIndex > 10 && dataIndex < 1)
{
MessageBox.Show("數據索引的取值範圍在1至10之間!","錯誤!",
MessageBoxButtons.OK,MessageBoxIcon.Error);
return r;
}
byte[] decrypted;
byte[] key = {106,51,25,141,157,142,23,111,234,159,187,154,215,34,37,204};
byte[] IV = {135,186,133,136,184,149,153,144};
System.Text.UnicodeEncoding textConverter = new UnicodeEncoding();
RC2CryptoServiceProvider rc2CSP = new RC2CryptoServiceProvider();
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>
/// 將一段文本加密後保存到一個文件
/// </summary>
/// <param name="toEncryptText">要加密的文本數據</param>
/// <param name="filePath">要保存的文件</param>
/// <returns>是否加密成功</returns>
public static bool EncryptToFile(string toEncryptText,string filePath)
{
bool r = false;
byte[] encrypted;
byte[] key = {106,51,25,141,157,142,23,111,234,159,187,154,215,34,37,204};
byte[] IV = {135,186,133,136,184,149,153,144};
System.Text.UnicodeEncoding textConverter = new UnicodeEncoding();
RC2CryptoServiceProvider rc2CSP = new RC2CryptoServiceProvider();
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>
/// 將一個被加密的文件解密
/// </summary>
/// <param name="filePath">要解密的文件</param>
/// <returns>解密後的文本</returns>
public static string DecryptFromFile(string filePath)
{
string r = "";
byte[] decrypted;
byte[] key = {106,51,25,141,157,142,23,111,234,159,187,154,215,34,37,204};
byte[] IV = {135,186,133,136,184,149,153,144};
System.Text.UnicodeEncoding textConverter = new UnicodeEncoding();
RC2CryptoServiceProvider rc2CSP = new RC2CryptoServiceProvider();
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;
}
}
}