/// <summary>
/// 对文件加密采用算法
/// </summary>
/// <param name="sy">创建一个公钥和一个私钥 </param>
private void PasswordToByte(SymmetricAlgorithm sy)
{
byte[] b = new byte[8];
byte[] c = new byte[8];
Encoding ascii = Encoding.ASCII;
byte[] EncodeByte = ascii.GetBytes("double90001");
byte[] EncodeByte2 = ascii.GetBytes("double90001"); ToPassByte(b, EncodeByte);
ToPassByte(c, EncodeByte2); sy.Key = b;
sy.IV = c;
} /// <summary>
///
/// </summary>
/// <param name="Destination">字节数 </param>
/// <param name="Source">编码字符数组 </param>
public void ToPassByte(byte[] Destination, byte[] Source)
{
if (Destination.Length >= Source.Length)
{
for (int i = 0; i < Source.Length; i++)
{
Destination[i] = Source[i];
}
}
else
{
for (int i = 0; i < Destination.Length; i++)
{
Destination[i] = Source[i];
}
}
}这是公钥私钥的方法。
/// <summary>
/// 将一个文件变为加密流并存入数组
/// </summary>
/// <param name="inName">需要加密文件的全路径 </param>
public byte[] EncryptData(String inName)
{
//创建输入流和输出流
FileStream fin = new FileStream(inName, FileMode.Open, FileAccess.Read);
MemoryStream fout = new MemoryStream();
fout.SetLength(0);
//读写的缓存区
byte[] bin = new byte[1000]; //加密的临时存储区
long rdlen = 0; //初始化写出流的长度
long totlen = fin.Length; //输入流的长度
int len; //某一个时间段完成的写出流长度
SymmetricAlgorithm des = new DESCryptoServiceProvider();
//给key和iv赋值
PasswordToByte(des);
//创建加密器
ICryptoTransform transform = des.CreateEncryptor(des.Key, des.IV);
//使用加密器和输出流,创建一个加密输出流
CryptoStream encStream = new CryptoStream(fout, transform, CryptoStreamMode.Write);
//循环读出输入流到内存中,然后加密流将一段内存加密后写到输出流
while (rdlen < totlen)
{
len = fin.Read(bin, 0, 1000);
encStream.Write(bin, 0, len);
rdlen = rdlen + len;
}
byte[] fdata = fout.ToArray(); //将加密流fout储存到数组fdata中
//关闭流
encStream.FlushFinalBlock();
encStream.Close();
fin.Close();
fout.Close();
return fdata;
}这个是加密函数,输入一个文件的全路径,通过对文件的加密返回一个比特数组,再传到服务器端(webservice)进行解密。
/// <summary>
///解密
/// </summary>
/// <param name="filedata"> 存储文件流的比特数组</param>
/// <param name="outName"> 要输出的文件全路径及名称</param>
public void DecryptData(byte[] filedata, string outName)
{
//创建输出流
FileStream fout = new FileStream(outName, FileMode.OpenOrCreate, FileAccess.Write);
fout.SetLength(0);
SymmetricAlgorithm des = new DESCryptoServiceProvider();
//给key和iv赋值
PasswordToByte(des);
// 创建解密器
ICryptoTransform transform = des.CreateDecryptor(des.Key, des.IV);
//使用解密器和输出流,创建一个解密输出流
CryptoStream encStream = new CryptoStream(fout, transform, CryptoStreamMode.Write);
//解密和写输出流
encStream.Write(filedata, 0, (int)filedata.Length);
//关闭流
encStream.Flush(); //错误地方****************
fout.Close();
}这个是解密函数。
问题是在解密过程中产生的,如果我把encStream.Flush()改为encStream.Close()或者是encStream.FlushFinalBlock();encStream.Close();就会报“不正确的数据”。 虽然encStream.Flush()可以通过并且编译不会错,但是很严重的问题发生了,通过逐语句调试会发现,加密过程中所有数据都很正常,但是解密后的数据明显少了几个字节,运行后实际得到的文件(如txt文件)打开后发现里面的确少了几个字。不知道是什么原因,找了很久了,不知道哪位高手能帮忙检查指点一下,谢谢!!!!!
我个人觉得问题出在解密过程中,但是找了半天不知道怎么处理。
发现出问题的地方不在解密过程,而是在加密过程,
具体的说就是加密时生产字节数组的地方。
/// <summary>
/// 将一个文件变为加密流并存入数组
/// </summary>
/// <param name="inName">需要加密文件的全路径 </param>
public byte[] EncryptData(String inName)
{
//创建输入流和输出流
FileStream fin = new FileStream(inName, FileMode.Open, FileAccess.Read);
MemoryStream fout = new MemoryStream();
fout.SetLength(0);
//读写的缓存区
byte[] bin = new byte[1000]; //加密的临时存储区
long rdlen = 0; //初始化写出流的长度
long totlen = fin.Length; //输入流的长度
int len; //某一个时间段完成的写出流长度
SymmetricAlgorithm des = new DESCryptoServiceProvider();
//给key和iv赋值
PasswordToByte(des);
//创建加密器
ICryptoTransform transform = des.CreateEncryptor(des.Key, des.IV);
//使用加密器和输出流,创建一个加密输出流
CryptoStream encStream = new CryptoStream(fout, transform, CryptoStreamMode.Write);
//循环读出输入流到内存中,然后加密流将一段内存加密后写到输出流
while (rdlen < totlen)
{
len = fin.Read(bin, 0, 1000);
encStream.Write(bin, 0, len);
rdlen = rdlen + len;
} encStream.FlushFinalBlock(); //将此方法放在前面,同时应该也可以解决解密时Flush出错的问题。
byte[] fdata = fout.ToArray(); //将加密流fout储存到数组fdata中
//关闭流
encStream.Close();
fin.Close();
fout.Close();
return fdata;
}