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();
}
///
1<summary>
2/// 新建一个大小为10261B的文件,以便将加密数据写入固定大小的文件。
3/// </summary>
///
1<param name="filePath"/>
文件保存的地址,包含文件名
public 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);
}
}
///
1<summary>
2/// 将文本数据加密后写入一个文件,其中,这个文件是用InitBinFile建立的,这个文件将被分成十块,
3/// 用来分别保存10组不同的数据,第一个byte位保留,第2位到第21位分别用来存放每块数据的长度,但
4/// 一个byte的取值为0-127,所以,用两个byte来存放一个长度。
5/// </summary>
///
1<param name="toEncryptText"/>
要加密的文本数据
///
1<param name="filePath"/>
要写入的文件
///
1<param name="dataIndex"/>
写入第几块,取值为1--10
///
1<returns>是否操作成功</returns>
public 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;
//打开要写入的文件,主要是为了保持原文件的内容不丢失
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(this.key,this.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[dataIndex2 - 1] = Convert.ToByte(Convert.ToString(encrypted.Length/128));
index[dataIndex2] = Convert.ToByte(Convert.ToString(encrypted.Length%128));
//将加密后的结果写入index(覆盖)
for(int i=0;i
1<encrypted.length;i++) <summary="" filestream(filepath,="" index[1024*(dataindex-1)+21+i]="encrypted[i];" r="true;" r;="" return="" system.io.fileaccess.write,="" system.io.filemode.truncate,="" system.io.fileshare.none,1024,true);="" tmpfilestream="new" tmpfilestream.close();="" tmpfilestream.flush();="" tmpfilestream.write(index,0,10261);="" }="" 写文件="" 建立文件流="">
2/// 从一个文件中解密出一段文本,其中,这个文件是由InitBinFile建立的,并且由 EncryptToFile加密的
3///
4/// <param name="filePath"/>要解密的文件
5/// <param name="dataIndex"/>要从哪一个块中解密
6/// <returns>解密后的文本</returns>
7public string DecryptFromFile(string filePath,int dataIndex)
8{
9string r = "";
10if(dataIndex > 10 && dataIndex < 1)
11{
12MessageBox.Show("数据索引的取值范围在1至10之间!","错误!",
13MessageBoxButtons.OK,MessageBoxIcon.Error);
14return r;
15}
16byte[] decrypted;
17System.IO.FileStream tmpFileStream = new FileStream(filePath,
18System.IO.FileMode.Open,
19System.IO.FileAccess.Read,
20System.IO.FileShare.None,1024,true);
21
22System.Security.Cryptography.ICryptoTransform Decryptor = rc2CSP.CreateDecryptor(this.key,this.iv);
23System.IO.MemoryStream msDecrypt = new MemoryStream();
24System.Security.Cryptography.CryptoStream csDecrypt = new CryptoStream(msDecrypt,
25Decryptor,CryptoStreamMode.Write);
26byte[] index = new byte[10261];
27
28tmpFileStream.Read(index,0,10261);
29int startIndex = 1024*(dataIndex-1)+21;
30int count = index[dataIndex*2 - 1]*128 + index[dataIndex*2];
31byte[] tmp = new byte[count];
32
33Array.Copy(index,1024*(dataIndex-1)+21,tmp,0,count);
34csDecrypt.Write(tmp,0,count);
35csDecrypt.FlushFinalBlock();
36decrypted = msDecrypt.ToArray();
37r = textConverter.GetString(decrypted,0,decrypted.Length);
38tmpFileStream.Close();
39return r;
40}
41/// <summary>
42/// 将一段文本加密后保存到一个文件
43/// </summary>
44/// <param name="toEncryptText"/>要加密的文本数据
45/// <param name="filePath"/>要保存的文件
46/// <returns>是否加密成功</returns>
47public bool EncryptToFile(string toEncryptText,string filePath)
48{
49bool r = false;
50byte[] encrypted;
51System.IO.FileStream tmpFileStream = new FileStream(filePath,
52System.IO.FileMode.OpenOrCreate,
53System.IO.FileAccess.Write,
54System.IO.FileShare.None,1024,true);
55
56System.Security.Cryptography.ICryptoTransform Encryptor = rc2CSP.CreateEncryptor(this.key,this.iv);
57System.IO.MemoryStream msEncrypt = new MemoryStream();
58System.Security.Cryptography.CryptoStream csEncrypt = new CryptoStream(msEncrypt,
59Encryptor,CryptoStreamMode.Write);
60
61byte[] tmp = textConverter.GetBytes(toEncryptText);
62csEncrypt.Write(tmp,0,tmp.Length);
63csEncrypt.FlushFinalBlock();
64encrypted = msEncrypt.ToArray();
65tmpFileStream.Write(encrypted,0,encrypted.Length);
66tmpFileStream.Flush();
67r = true;
68tmpFileStream.Close();
69return r;
70}
71/// <summary>
72/// 将一个被加密的文件解密
73/// </summary>
74/// <param name="filePath"/>要解密的文件
75/// <returns>解密后的文本</returns>
76public string DecryptFromFile(string filePath)
77{
78string r = "";
79byte[] decrypted;
80System.IO.FileStream tmpFileStream = new FileStream(filePath,
81System.IO.FileMode.Open,
82System.IO.FileAccess.Read,
83System.IO.FileShare.None,1024,true);
84System.Security.Cryptography.ICryptoTransform Decryptor = rc2CSP.CreateDecryptor(this.key,this.iv);
85System.IO.MemoryStream msDecrypt = new MemoryStream();
86System.Security.Cryptography.CryptoStream csDecrypt = new CryptoStream(msDecrypt,
87Decryptor,CryptoStreamMode.Write);
88
89byte[] tmp = new byte[tmpFileStream.Length];
90tmpFileStream.Read(tmp,0,tmp.Length);
91csDecrypt.Write(tmp,0,tmp.Length);
92csDecrypt.FlushFinalBlock();
93decrypted = msDecrypt.ToArray();
94r = textConverter.GetString(decrypted,0,decrypted.Length);
95tmpFileStream.Close();
96return r;
97}
98//-------------------------------------------------------------
99/// <summary>
100/// 将文本数据加密后写入一个文件,其中,这个文件是用InitBinFile建立的,这个文件将被分成十块,
101/// 用来分别保存10组不同的数据,第一个byte位保留,第2位到第21位分别用来存放每块数据的长度,但
102/// 一个byte的取值为0-127,所以,用两个byte来存放一个长度。
103/// </summary>
104/// <param name="toEncryptText"/>要加密的文本数据
105/// <param name="filePath"/>要写入的文件
106/// <param name="dataIndex"/>写入第几块,取值为1--10
107/// <param name="IV"/>初始化向量
108/// <param name="Key"/>加密密匙
109/// <returns>是否操作成功</returns>
110public bool EncryptToFile(string toEncryptText,string filePath,int dataIndex,byte[] IV,byte[] Key)
111{
112bool r = false;
113if(dataIndex > 10 && dataIndex < 1)
114{
115MessageBox.Show("数据索引的取值范围在1至10之间!","错误!",
116MessageBoxButtons.OK,MessageBoxIcon.Error);
117return r;
118}
119byte[] encrypted;
120//打开要写入的文件,主要是为了保持原文件的内容不丢失
121System.IO.FileStream tmpFileStream= new FileStream(filePath,
122System.IO.FileMode.Open,
123System.IO.FileAccess.Read,
124System.IO.FileShare.None,1024,true);
125
126byte[] index = new byte[10261];
127//将读取的内容写到byte数组
128tmpFileStream.Read(index,0,10261);
129tmpFileStream.Close();
130//定义基本的加密转换运算
131System.Security.Cryptography.ICryptoTransform Encryptor = rc2CSP.CreateEncryptor(Key,IV);
132System.IO.MemoryStream msEncrypt = new MemoryStream();
133//在此加密转换流中,加密将从csEncrypt,加密后,结果在msEncrypt流中。
134System.Security.Cryptography.CryptoStream csEncrypt = new CryptoStream(msEncrypt,
135Encryptor,CryptoStreamMode.Write);
136//将要加密的文本转换成UTF-16 编码,保存在tmp数组。
137byte[] tmp = textConverter.GetBytes(toEncryptText);
138//将tmp输入csEncrypt,将通过Encryptor来加密。
139csEncrypt.Write(tmp,0,tmp.Length);
140//输出到msEnctypt
141csEncrypt.FlushFinalBlock();
142//将流转成byte[]
143encrypted = msEncrypt.ToArray();
144if(encrypted.Length>1024)
145{
146MessageBox.Show("加密后,数据长度大于1KB,无法保存");
147return false;
148}
149//得到加密后数据的大小,将结果存在指定的位置。
150index[dataIndex*2 - 1] = Convert.ToByte(Convert.ToString(encrypted.Length/128));
151index[dataIndex*2] = Convert.ToByte(Convert.ToString(encrypted.Length%128));
152//将加密后的结果写入index(覆盖)
153for(int i=0;i<encrypted.length;i++) <summary="" filestream(filepath,="" index[1024*(dataindex-1)+21+i]="encrypted[i];" r="true;" r;="" return="" system.io.fileaccess.write,="" system.io.filemode.truncate,="" system.io.fileshare.none,1024,true);="" tmpfilestream="new" tmpfilestream.close();="" tmpfilestream.flush();="" tmpfilestream.write(index,0,10261);="" }="" 写文件="" 建立文件流="">
154/// 从一个文件中解密出一段文本,其中,这个文件是由InitBinFile建立的,并且由 EncryptToFile加密的
155///
156/// <param name="filePath"/>要解密的文件
157/// <param name="dataIndex"/>要从哪一个块中解密
158/// <param name="IV"/>初始化向量
159/// <param name="Key"/>解密密匙
160/// <returns>解密后的文本</returns>
161public string DecryptFromFile(string filePath,int dataIndex,byte[] IV,byte[] Key)
162{
163string r = "";
164if(dataIndex > 10 && dataIndex < 1)
165{
166MessageBox.Show("数据索引的取值范围在1至10之间!","错误!",
167MessageBoxButtons.OK,MessageBoxIcon.Error);
168return r;
169}
170byte[] decrypted;
171System.IO.FileStream tmpFileStream = new FileStream(filePath,
172System.IO.FileMode.Open,
173System.IO.FileAccess.Read,
174System.IO.FileShare.None,1024,true);
175
176System.Security.Cryptography.ICryptoTransform Decryptor = rc2CSP.CreateDecryptor(Key,IV);
177System.IO.MemoryStream msDecrypt = new MemoryStream();
178System.Security.Cryptography.CryptoStream csDecrypt = new CryptoStream(msDecrypt,
179Decryptor,CryptoStreamMode.Write);
180byte[] index = new byte[10261];
181
182tmpFileStream.Read(index,0,10261);
183int startIndex = 1024*(dataIndex-1)+21;
184int count = index[dataIndex*2 - 1]*128 + index[dataIndex*2];
185byte[] tmp = new byte[count];
186
187Array.Copy(index,1024*(dataIndex-1)+21,tmp,0,count);
188csDecrypt.Write(tmp,0,count);
189csDecrypt.FlushFinalBlock();
190decrypted = msDecrypt.ToArray();
191r = textConverter.GetString(decrypted,0,decrypted.Length);
192tmpFileStream.Close();
193return r;
194}
195/// <summary>
196/// 将一段文本加密后保存到一个文件
197/// </summary>
198/// <param name="toEncryptText"/>要加密的文本数据
199/// <param name="filePath"/>要保存的文件
200/// <param name="IV"/>初始化向量
201/// <param name="Key"/>加密密匙
202/// <returns>是否加密成功</returns>
203public bool EncryptToFile(string toEncryptText,string filePath,byte[] IV,byte[] Key)
204{
205bool r = false;
206byte[] encrypted;
207System.IO.FileStream tmpFileStream = new FileStream(filePath,
208System.IO.FileMode.OpenOrCreate,
209System.IO.FileAccess.Write,
210System.IO.FileShare.None,1024,true);
211
212System.Security.Cryptography.ICryptoTransform Encryptor = rc2CSP.CreateEncryptor(Key,IV);
213System.IO.MemoryStream msEncrypt = new MemoryStream();
214System.Security.Cryptography.CryptoStream csEncrypt = new CryptoStream(msEncrypt,
215Encryptor,CryptoStreamMode.Write);
216
217byte[] tmp = textConverter.GetBytes(toEncryptText);
218csEncrypt.Write(tmp,0,tmp.Length);
219csEncrypt.FlushFinalBlock();
220encrypted = msEncrypt.ToArray();
221tmpFileStream.Write(encrypted,0,encrypted.Length);
222tmpFileStream.Flush();
223r = true;
224tmpFileStream.Close();
225return r;
226}
227/// <summary>
228/// 将一个被加密的文件解密
229/// </summary>
230/// <param name="filePath"/>要解密的文件
231/// <param name="IV"/>初始化向量
232/// <param name="Key"/>解密密匙
233/// <returns>解密后的文本</returns>
234public string DecryptFromFile(string filePath,byte[] IV,byte[] Key)
235{
236string r = "";
237byte[] decrypted;
238System.IO.FileStream tmpFileStream = new FileStream(filePath,
239System.IO.FileMode.Open,
240System.IO.FileAccess.Read,
241System.IO.FileShare.None,1024,true);
242System.Security.Cryptography.ICryptoTransform Decryptor = rc2CSP.CreateDecryptor(Key,IV);
243System.IO.MemoryStream msDecrypt = new MemoryStream();
244System.Security.Cryptography.CryptoStream csDecrypt = new CryptoStream(msDecrypt,
245Decryptor,CryptoStreamMode.Write);
246
247byte[] tmp = new byte[tmpFileStream.Length];
248tmpFileStream.Read(tmp,0,tmp.Length);
249csDecrypt.Write(tmp,0,tmp.Length);
250csDecrypt.FlushFinalBlock();
251decrypted = msDecrypt.ToArray();
252r = textConverter.GetString(decrypted,0,decrypted.Length);
253tmpFileStream.Close();
254return r;
255}
256/// <summary>
257/// 设置加密或解密的初始化向量
258/// </summary>
259/// <param name="s"/>长度等于8的ASCII字符集的字符串
260public void SetIV(string s)
261{
262if(s.Length != 8)
263{
264MessageBox.Show("输入的字符串必须为长度为8的且属于ASCII字符集的字符串");
265this.iv =null;
266return;
267}
268try
269{
270this.iv = this.asciiEncoding.GetBytes(s);
271}
272catch(System.Exception)
273{
274MessageBox.Show("输入的字符串必须为长度为8的且属于ASCII字符集的字符串");
275this.iv = null;
276}
277}
278/// <summary>
279/// 设置加密或解密的密匙
280/// </summary>
281/// <param name="s"/>长度等于16的ASCII字符集的字符串
282public void SetKey(string s)
283{
284if(s.Length != 16)
285{
286MessageBox.Show("输入的字符串必须为长度为16的且属于ASCII字符集的字符串");
287this.key = null;
288return;
289}
290try
291{
292this.key = this.asciiEncoding.GetBytes(s);
293}
294catch(System.Exception)
295{
296MessageBox.Show("输入的字符串必须为长度为16的且属于ASCII字符集的字符串");
297this.key = null;
298}
299}
300}
301}</encrypted.length;i++)></encrypted.length;i++)>