积极答复者
DES解密遇到CryptographicException:不正确的数据。

问题
-
问题让我头疼两天,请大家指点一下,谢谢!
我写了两个方法,一个是DES加密,一个是DES解密,环境为VS2010,.NET4.0,使用C#,方法如下:
/// <summary> /// CBC-DES加密 /// </summary> public static byte[] DESEncrypt(byte[] data, byte[] key, byte[] iv) { //注:已省略检查参数合法性等代码,以缩短帖子长度 byte[] result = null; using (DES des = new DESCryptoServiceProvider() { Key = key, IV = iv }) using (MemoryStream outStream = new MemoryStream()) using (CryptoStream encStream = new CryptoStream(outStream, des.CreateEncryptor(), CryptoStreamMode.Write)) { encStream.Write(data, 0, data.Length); result = outStream.ToArray(); } return result; } /// <summary> /// CBC-DES解密 /// </summary> public static byte[] DESDecrypt(byte[] data, byte[] key, byte[] iv) { //注:已省略检查参数合法性等代码,以缩短帖子长度 byte[] result = null; using (DES des = new DESCryptoServiceProvider() { Key = key, IV = iv }) using (MemoryStream inStream = new MemoryStream(data)) using (CryptoStream encStream = new CryptoStream(inStream, des.CreateDecryptor(), CryptoStreamMode.Read)) { List<byte> byteList = new List<byte>(); int i; while ((i = encStream.ReadByte()) != -1) { byteList.Add((byte)i); } result = byteList.ToArray(); } return result; }
然后我就建立了几个数据测试它们,测试代码如下:
byte[] oriBytes = { 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4 }; //32个字节,做为被加密的内容。 byte[] key = { 225, 11, 183, 166, 175, 189, 133, 111 }; //8个字节,做为加密用的KEY byte[] iv = { 181, 12, 1, 234, 97, 154, 240, 3 }; //8个字节,做为加密用的IV byte[] desBytes = EncryptHelper.DESEncrypt(oriBytes, key, iv); //加密oriBytes,加密结果为desBytes。 byte[] oriBytes2 = EncryptHelper.DESDecrypt(desBytes, key, iv); //使用同样的key和iv解密desBytes,解密结果为oriBytes2。但只成功解密了前24个字节,解密第25字节时,DESDecrypt方法里的encStream.ReadByte()语句会抛出异常:不正确的数据。 bool isSuccess = desBytes.SequenceEqual(oriBytes2); //按照我的设想,desBytes里的内容应该和desBytes2里的内容一致,即isSuccess为true。但因为上句解密代码会抛异常,根本执行不到这一步。
我实现找到不错误的原因,我找了很多资料,还把baidu和google都翻了一遍,都没找到解决问题的方法。现在老板催,同事要,我的头都快炸啦,难道非得要到根据DES算法自己去XOR字节的地步么。各位大侠,快把我从地狱中救赎出来吧,谢谢!!!!!
Wantal
答案
-
你好:)
1)在DesEncypt函数中,你缺少了对Stream的Close操作,意味着你无法把数据写入到流中,注意我黑色、粗体、下划线部分——
using (DES des = new DESCryptoServiceProvider() { Key = key, IV = iv })
{
using (MemoryStream outStream = new MemoryStream())
{
using (CryptoStream encStream = new CryptoStream(outStream, des.CreateEncryptor(), CryptoStreamMode.Write))
{
encStream.Write(data, 0, data.Length);
encStream.Close();
result = outStream.ToArray();
}
}
}2)注意你比较:把加密前和加密后比较!
bool isSuccess = oriBytes2.SequenceEqual(oriBytes2);
以下给出完整代码:
namespace A
{
class Program
{
public static byte[] DESEncrypt(byte[] data, byte[] key, byte[] iv)
{
//注:已省略检查参数合法性等代码,以缩短帖子长度
byte[] result = null;
using (DES des = new DESCryptoServiceProvider() { Key = key, IV = iv })
{
using (MemoryStream outStream = new MemoryStream())
{
using (CryptoStream encStream = new CryptoStream(outStream, des.CreateEncryptor(), CryptoStreamMode.Write))
{
encStream.Write(data, 0, data.Length);
encStream.Close();
result = outStream.ToArray();
}
}
}
return result;
}
public static byte[] DESDecrypt(byte[] data, byte[] key, byte[] iv)
{
//注:已省略检查参数合法性等代码,以缩短帖子长度
byte[] result = null;
using (DES des = new DESCryptoServiceProvider() { Key = key, IV = iv })
using (MemoryStream inStream = new MemoryStream(data))
using (CryptoStream encStream = new CryptoStream(inStream, des.CreateDecryptor(), CryptoStreamMode.Read))
{
List<byte> byteList = new List<byte>();
int i;
while ((i = encStream.ReadByte()) != -1)
{
byteList.Add((byte)i);
}
result = byteList.ToArray();
}
return result;
}
static void Main(string[] args)
{
byte[] oriBytes = { 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4 };byte[] key = { 225, 11, 183, 166, 175, 189, 133, 111 };
byte[] iv = { 181, 12, 1, 234, 97, 154, 240, 3 };
byte[] desBytes = DESEncrypt(oriBytes, key, iv);
byte[] oriBytes2 = DESDecrypt(desBytes, key, iv);bool isSuccess = oriBytes2.SequenceEqual(oriBytes2);
Console.WriteLine(isSuccess);
}
}
}
QQ我:
下载MSDN桌面工具(Vista,Win7)
我的博客园
慈善点击,点击此处- 已编辑 ThankfulHeartModerator 2011年12月16日 7:08
- 已标记为答案 Wantal 2011年12月16日 7:26
全部回复
-
你好:)
1)在DesEncypt函数中,你缺少了对Stream的Close操作,意味着你无法把数据写入到流中,注意我黑色、粗体、下划线部分——
using (DES des = new DESCryptoServiceProvider() { Key = key, IV = iv })
{
using (MemoryStream outStream = new MemoryStream())
{
using (CryptoStream encStream = new CryptoStream(outStream, des.CreateEncryptor(), CryptoStreamMode.Write))
{
encStream.Write(data, 0, data.Length);
encStream.Close();
result = outStream.ToArray();
}
}
}2)注意你比较:把加密前和加密后比较!
bool isSuccess = oriBytes2.SequenceEqual(oriBytes2);
以下给出完整代码:
namespace A
{
class Program
{
public static byte[] DESEncrypt(byte[] data, byte[] key, byte[] iv)
{
//注:已省略检查参数合法性等代码,以缩短帖子长度
byte[] result = null;
using (DES des = new DESCryptoServiceProvider() { Key = key, IV = iv })
{
using (MemoryStream outStream = new MemoryStream())
{
using (CryptoStream encStream = new CryptoStream(outStream, des.CreateEncryptor(), CryptoStreamMode.Write))
{
encStream.Write(data, 0, data.Length);
encStream.Close();
result = outStream.ToArray();
}
}
}
return result;
}
public static byte[] DESDecrypt(byte[] data, byte[] key, byte[] iv)
{
//注:已省略检查参数合法性等代码,以缩短帖子长度
byte[] result = null;
using (DES des = new DESCryptoServiceProvider() { Key = key, IV = iv })
using (MemoryStream inStream = new MemoryStream(data))
using (CryptoStream encStream = new CryptoStream(inStream, des.CreateDecryptor(), CryptoStreamMode.Read))
{
List<byte> byteList = new List<byte>();
int i;
while ((i = encStream.ReadByte()) != -1)
{
byteList.Add((byte)i);
}
result = byteList.ToArray();
}
return result;
}
static void Main(string[] args)
{
byte[] oriBytes = { 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4 };byte[] key = { 225, 11, 183, 166, 175, 189, 133, 111 };
byte[] iv = { 181, 12, 1, 234, 97, 154, 240, 3 };
byte[] desBytes = DESEncrypt(oriBytes, key, iv);
byte[] oriBytes2 = DESDecrypt(desBytes, key, iv);bool isSuccess = oriBytes2.SequenceEqual(oriBytes2);
Console.WriteLine(isSuccess);
}
}
}
QQ我:
下载MSDN桌面工具(Vista,Win7)
我的博客园
慈善点击,点击此处- 已编辑 ThankfulHeartModerator 2011年12月16日 7:08
- 已标记为答案 Wantal 2011年12月16日 7:26