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ù)寫入固定大小的文件。
/// </summary>
/// <param name="filepath">文件保存的地址,包含文件名</param>
public void initbinfile(string filepath)
{
byte[] tmp = new byte[10261];
try //創(chuàng)建文件流,將其內(nèi)容全部寫入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ù)加密后寫入一個(gè)文件,其中,這個(gè)文件是用initbinfile建立的,這個(gè)文件將被分成十塊,
/// 用來分別保存10組不同的數(shù)據(jù),第一個(gè)byte位保留,第2位到第21位分別用來存放每塊數(shù)據(jù)的長(zhǎng)度,但
/// 一個(gè)byte的取值為0-127,所以,用兩個(gè)byte來存放一個(gè)長(zhǎng)度。
/// </summary>
/// <param name="toencrypttext">要加密的文本數(shù)據(jù)</param>
/// <param name="filepath">要寫入的文件</param>
/// <param name="dataindex">寫入第幾塊,取值為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;
//打開要寫入的文件,主要是為了保持原文件的內(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)容寫到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,將通過encryptor來加密。
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,無法保存");
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é)果寫入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>
/// 從一個(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ù)加密后寫入一個(gè)文件,其中,這個(gè)文件是用initbinfile建立的,這個(gè)文件將被分成十塊,
/// 用來分別保存10組不同的數(shù)據(jù),第一個(gè)byte位保留,第2位到第21位分別用來存放每塊數(shù)據(jù)的長(zhǎng)度,但
/// 一個(gè)byte的取值為0-127,所以,用兩個(gè)byte來存放一個(gè)長(zhǎng)度。
/// </summary>
/// <param name="toencrypttext">要加密的文本數(shù)據(jù)</param>
/// <param name="filepath">要寫入的文件</param>
/// <param name="dataindex">寫入第幾塊,取值為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;
//打開要寫入的文件,主要是為了保持原文件的內(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)容寫到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,將通過encryptor來加密。
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,無法保存");
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é)果寫入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>
/// 從一個(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;
}
}
}
}
中國(guó)最大的web開發(fā)資源網(wǎng)站及技術(shù)社區(qū),