源码如下:
/// <summary>
/// 解密给定的字符串
/// </summary>
/// <param name='str'>要解密的字符</param>
/// <returns></returns>
public string DecryptString(string str)
{
byte[] ivb=Encoding.ASCII.GetBytes(this.iv);
byte[] keyb=Encoding.ASCII.GetBytes(this.EncryptKey);
byte[] toDecrypt=this.EncodingMode.GetBytes(str);
byte[] deCrypted=new byte[toDecrypt.Length];
ICryptoTransform deCryptor=des.CreateDecryptor(keyb,ivb);
MemoryStream msDecrypt=new MemoryStream(toDecrypt);
CryptoStream csDecrypt=new CryptoStream(msDecrypt,deCryptor,CryptoStreamMode.Read);
try
{
csDecrypt.Read(deCrypted,0,deCrypted.Length);
}
catch(Exception err)
{
throw new ApplicationException(err.Message);
}
finally
{
try
{
msDecrypt.Close();
csDecrypt.Close();
}
catch{;}
}
return this.EncodingMode.GetString(deCrypted);
}
为什么会出现这个问题?
/// <summary>
/// 解密给定的字符串
/// </summary>
/// <param name='str'>要解密的字符</param>
/// <returns></returns>
public string DecryptString(string str)
{
byte[] ivb=Encoding.ASCII.GetBytes(this.iv);
byte[] keyb=Encoding.ASCII.GetBytes(this.EncryptKey);
byte[] toDecrypt=this.EncodingMode.GetBytes(str);
byte[] deCrypted=new byte[toDecrypt.Length];
ICryptoTransform deCryptor=des.CreateDecryptor(keyb,ivb);
MemoryStream msDecrypt=new MemoryStream(toDecrypt);
CryptoStream csDecrypt=new CryptoStream(msDecrypt,deCryptor,CryptoStreamMode.Read);
try
{
csDecrypt.Read(deCrypted,0,deCrypted.Length);
}
catch(Exception err)
{
throw new ApplicationException(err.Message);
}
finally
{
try
{
msDecrypt.Close();
csDecrypt.Close();
}
catch{;}
}
return this.EncodingMode.GetString(deCrypted);
}
为什么会出现这个问题?
using System;
using System.Security.Cryptography;
using System.IO;
using System.Text;
//方法
//加密方法
public string Encrypt(string pToEncrypt, string sKey)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
//把字符串放到byte数组中
//原来使用的UTF8编码,我改成Unicode编码了,不行
byte[] inputByteArray = Encoding.Default.GetBytes(pToEncrypt);
//byte[] inputByteArray=Encoding.Unicode.GetBytes(pToEncrypt);
//建立加密对象的密钥和偏移量
//原文使用ASCIIEncoding.ASCII方法的GetBytes方法
//使得输入密码必须输入英文文本
des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(),CryptoStreamMode.Write);
//Write the byte array into the crypto stream
//(It will end up in the memory stream)
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
//Get the data back from the memory stream, and into a string
StringBuilder ret = new StringBuilder();
foreach(byte b in ms.ToArray())
{
//Format as hex
ret.AppendFormat("{0:X2}", b);
}
ret.ToString();
return ret.ToString();
}
//解密方法
public string Decrypt(string pToDecrypt, string sKey)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
//Put the input string into the byte array
byte[] inputByteArray = new byte[pToDecrypt.Length / 2];
for(int x = 0; x < pToDecrypt.Length / 2; x++)
{
int i = (Convert.ToInt32(pToDecrypt.Substring(x * 2, 2), 16));
inputByteArray[x] = (byte)i;
}
//建立加密对象的密钥和偏移量,此值重要,不能修改
des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(),CryptoStreamMode.Write);
//Flush the data through the crypto stream into the memory stream
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
//Get the decrypted data back from the memory stream
//建立StringBuild对象,CreateDecrypt使用的是流对象,必须把解密后的文本变成流对象
StringBuilder ret = new StringBuilder();
return System.Text.Encoding.Default.GetString(ms.ToArray());
}
试试行不行!
/// 文件加密
/// </summary>
/// <param name="inFileName">需要加密的文件(文件的完整路径)</param>
/// <param name="outFileName">加密后的文件(文件的完整路径)</param>
/// <param name="sAlgorithm">对称算法实例</param>
/// <returns>bool</returns>
private bool EncryptFile(string InFileName, string OutFileName, SymmetricAlgorithm sAlgorithm)
{
try
{
//创建加密文件流
FileStream inFileStream = new FileStream(InFileName, FileMode.Open, FileAccess.Read);
FileStream outFileStream = new FileStream(OutFileName, FileMode.OpenOrCreate, FileAccess.Write); //锁定被加密文件
inFileStream.Lock(0, inFileStream.Length);
//设定加密后文件的初始长度
outFileStream.SetLength(0); long fileLength = inFileStream.Length; //文件的总字节数组长度
byte[] bytein = new byte[100]; //每次以100个字节读取需要加密的文件
long readedlen = 0; //记录已被读取的字节位置
int len = 0; //每次写入的字节长度
CryptoStream encStream = new CryptoStream(outFileStream, sAlgorithm.CreateEncryptor(this.KeyValue, this.IVValue), CryptoStreamMode.Write);
try
{
while (readedlen < fileLength)
{
len = inFileStream.Read(bytein, 0, 100);//从输入流中读取100字节数组数据到bytein缓冲区
encStream.Write(bytein, 0, 100);
readedlen = readedlen + len;
}
outFileStream.Flush();
inFileStream.Flush();
encStream.Flush();
return true;
}
catch (Exception error)
{
throw (error);
}
finally
{
inFileStream.Unlock(0, inFileStream.Length);
encStream.Close();
inFileStream.Close();
outFileStream.Close();
}
}
catch (Exception error)
{
throw (error);
}
}
程序代码: /// <summary>
/// 文件解密
/// </summary>
/// <param name="inFileName">需要解密的文件(文件的完整路径)</param>
/// <param name="outFileName">解密后的文件(文件的完整路径)</param>
/// <param name="sAlgorithm">对称算法实例</param>
/// <returns>bool</returns>
public bool DecryptFile(string InFileName, string OutFileName, SymmetricAlgorithm sAlgorithm)
{
try
{
//创建解密文件流
FileStream inFileStream = new FileStream(InFileName, FileMode.Open, FileAccess.Read);
FileStream outFileStream = new FileStream(OutFileName, FileMode.OpenOrCreate, FileAccess.Write);
//设定加密后文件的初始长度
outFileStream.SetLength(0);
long fileLength = inFileStream.Length; //文件的总字节数组长度
byte[] bytein = new byte[100]; //每次以100个字节读取需要加密的文件
long readedlen = 0; //记录已被读取的字节位置
int len = 0; //每次写入的字节长度
CryptoStream encStream = new CryptoStream(outFileStream, sAlgorithm.CreateDecryptor(this.KeyValue, this.IVValue), CryptoStreamMode.Write);
try
{
while (readedlen < fileLength)
{
len = inFileStream.Read(bytein, 0, 100);//从输入流中读取100字节数组数据到bytein缓冲区
encStream.Write(bytein, 0, 100);
readedlen = readedlen + len;
}
outFileStream.Flush();
inFileStream.Flush();
encStream.FlushFinalBlock(); //加了这一句,有的时候就会出现异常,不知道为什么
return true;
}
catch (Exception error)
{
throw (error);
}
finally
{
encStream.Close(); //加了这一句,有的时候就会出现异常,不知道为什么
inFileStream.Close();
outFileStream.Close();
}
}
catch (Exception error)
{
throw (error);
}
} 上面的解密方法中,红颜色标识的两行代码,在有些情况下就会提示我上面所说的两种异常,到现在我唯一能稍微明白的是可能因为我加密后立即解密就会出现上面的异常情况,因为我查了好多资料都没有提示有这两种异常的出现。下面是我加密解密方法我改成操作内存流的代码,下面的代码能正常执行。
加密:
程序代码: /// <summary>
/// 文件加密
/// </summary>
/// <param name="inFileName">需要加密的文件(文件的完整路径)</param>
/// <param name="outFileName">加密后的文件(文件的完整路径)</param>
/// <param name="sAlgorithm">对称算法实例</param>
/// <returns>bool</returns>
private bool EncryptFile(string InFileName, string OutFileName, SymmetricAlgorithm sAlgorithm)
{
//将文件内容读取到字节数组
FileStream inFileStream = new FileStream(InFileName, FileMode.Open, FileAccess.Read);
byte[] sourceByte = new byte[inFileStream.Length];
inFileStream.Read(sourceByte, 0, sourceByte.Length);
inFileStream.Flush();
inFileStream.Close(); MemoryStream encryptStream = new MemoryStream();
CryptoStream encStream = new CryptoStream(encryptStream, sAlgorithm.CreateEncryptor(), CryptoStreamMode.Write);
try
{
//利用链接流加密源字节数组
encStream.Write(sourceByte, 0, sourceByte.Length);
encStream.FlushFinalBlock(); //将字节数组信息写入指定文件
FileStream outFileStream= new FileStream(OutFileName, FileMode.OpenOrCreate, FileAccess.Write);
BinaryWriter bWriter = new BinaryWriter(outFileStream);
bWriter.Write(encryptStream.ToArray());
encryptStream.Flush(); bWriter.Close();
encryptStream.Close();
}
catch (Exception error)
{
throw (error);
}
finally
{
encryptStream.Close();
encStream.Close();
}
return true;
}
对应的解密方法:
程序代码: /// <summary>
/// 文件解密
/// </summary>
/// <param name="inFileName">需要解密的文件(文件的完整路径)</param>
/// <param name="outFileName">解密后的文件(文件的完整路径)</param>
/// <param name="sAlgorithm">对称算法实例</param>
/// <returns>bool</returns>
public bool DecryptFile(string InFileName, string OutFileName, SymmetricAlgorithm sAlgorithm)
{ //读取被加密文件到字节数组
FileStream encryptFileStream= new FileStream(InFileName, FileMode.Open, FileAccess.Read);
byte[] encryptByte = new byte[encryptFileStream.Length];
encryptFileStream.Read(encryptByte, 0, encryptByte.Length);
encryptFileStream.Flush();
encryptFileStream.Close();
MemoryStream decryptStream = new MemoryStream();
CryptoStream encStream = new CryptoStream(decryptStream, sAlgorithm.CreateDecryptor(), CryptoStreamMode.Write);
try
{
encStream.Write(encryptByte, 0, encryptByte.Length);
encStream.FlushFinalBlock(); byte[] decryptByte = decryptStream.ToArray();
FileStream decryptFileStream= new FileStream(OutFileName, FileMode.OpenOrCreate, FileAccess.Write);
BinaryWriter bWriter = new BinaryWriter(decryptFileStream, Encoding.GetEncoding("GB18030"));
bWriter.Write(decryptByte);
decryptFileStream.Flush(); bWriter.Close();
decryptFileStream.Close();
}
catch (Exception error)
{
throw (error);
}
finally
{
decryptStream.Close();
encStream.Close();
} return true;
}
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Security.Cryptography;
using System.IO;namespace DES加密解密
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
} private void button1_Click(object sender, EventArgs e)
{
this.textBox2.Text = DESEncrypt("" + this.textBox1.Text.ToString().Trim() + "");
} //加密
public string DESEncrypt(string pToEncrypt)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
try
{
byte[] inputByteArray = Encoding.Default.GetBytes(pToEncrypt);
//密匙和偏移量
byte[] kkk = new byte[] { 0x16, 0x09, 0x14, 0x15, 0x07, 0x01, 0x05, 0x08 };
byte[] iivv = new byte[] { 0x08, 0x05, 0x01, 0x07, 0x15, 0x14, 0x09, 0x16 };
des.Key = kkk;
des.IV = iivv; MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
StringBuilder ret = new StringBuilder();
foreach (byte b in ms.ToArray())
{
ret.AppendFormat("{0:X2}", b);
}
ret.ToString();
return ret.ToString();
}
catch
{
return "";
} } private void button2_Click(object sender, EventArgs e)
{
this.textBox3.Text = DESDecrypt("" + this.textBox2.Text.ToString().Trim() + "");
}
//解密
public string DESDecrypt(string pToDecrypt)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
try
{
byte[] inputByteArray = new byte[pToDecrypt.Length / 2];
for (int x = 0; x < pToDecrypt.Length / 2; x++)
{
int i = (Convert.ToInt32(pToDecrypt.Substring(x * 2, 2), 16));
inputByteArray[x] = (byte)i;
} byte[] kkk = new byte[] { 0x16, 0x09, 0x14, 0x15, 0x07, 0x01, 0x05, 0x08 };
byte[] iivv = new byte[] { 0x08, 0x05, 0x01, 0x07, 0x15, 0x14, 0x09, 0x16 };
des.Key = kkk;
des.IV = iivv; MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock(); StringBuilder ret = new StringBuilder(); return System.Text.Encoding.Default.GetString(ms.ToArray());
}
catch
{
return "";
}
}
}
}
原理不明。似乎涉及内存问题。而且微软自己的例子里还要把key的内存部分锁住。
希望处女贴能给大家点帮助。
http://social.msdn.microsoft.com/Forums/zh-CN/2212/thread/f97717cb-4e23-48cd-b078-e33348f75bed