DES解密出现-“不正确的数据”和“要解密的数据长度无效”-问题,高手来解决!在线等!

shen521941 2007-09-14 01:03:33
源码如下:
/// <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);
}
为什么会出现这个问题?
...全文
3035 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
wantalcs 2011-12-17
  • 打赏
  • 举报
回复 1
虽然是2007年的帖子了,但考虑到依然会有人搜索到这帖,为了帮助像我这样搜索到儿还无能为力的人,就把解决问题的方法跟一下吧:
http://social.msdn.microsoft.com/Forums/zh-CN/2212/thread/f97717cb-4e23-48cd-b078-e33348f75bed
钝忆思梦 2011-08-04
  • 打赏
  • 举报
回复
我的也不行,都搞了一整天了,为什么勒。
怪怪 2011-08-03
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 topguy2046 的回复:]

哈,新来乍到。这个我刚才自己试了一个多钟头搞明白了,记住不断把能Flush的CryptoStream赶紧Flush了,然后再赶紧close就行了。
原理不明。似乎涉及内存问题。而且微软自己的例子里还要把key的内存部分锁住。
希望处女贴能给大家点帮助。
[/Quote]
我flush了,还是不行,呵呵.
Topguy2046 2011-05-26
  • 打赏
  • 举报
回复
哈,新来乍到。这个我刚才自己试了一个多钟头搞明白了,记住不断把能Flush的CryptoStream赶紧Flush了,然后再赶紧close就行了。
原理不明。似乎涉及内存问题。而且微软自己的例子里还要把key的内存部分锁住。
希望处女贴能给大家点帮助。
kay002 2011-05-09
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 flylingc 的回复:]
我的也出现这种问题
[/Quote]

悲剧,我2011年5月9日17:54:53
来过
FlyLingc 2009-12-31
  • 打赏
  • 举报
回复
我的也出现这种问题
HowkWolf 2009-01-12
  • 打赏
  • 举报
回复
俺也出现了,我也是在内存留中搞的,还在找原因。
wyman25 2008-10-03
  • 打赏
  • 举报
回复
我现在也出现了这种问题,我是使用内存流的形式的,就是新建一个加密流使用,构造函数使用了一个内存流,但结果是加密正常,解密就出现了“要解密的数据的长度无效”的错误,我怀疑是密匙的错误,我也很头疼。另外,我对文件的加密解密都是操作同一个文件的,而不是将操作结果另外创建为一个文件,这点我也觉得很有可疑。
shen521941 2007-09-14
  • 打赏
  • 举报
回复
来个人解决下
shen521941 2007-09-14
  • 打赏
  • 举报
回复
啊,晕 啊,你上面的我在网上也看过,但我看我的就没问题,不知道问题出在哪了 !
liutong606 2007-09-14
  • 打赏
  • 举报
回复
using System;
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 "";
}
}




}
}
叶子 2007-09-14
  • 打赏
  • 举报
回复
上面的文件加密方法在加密的时候没有任何问题,但是同样的,稍微修改下,下面是对应的解密的方法:
程序代码:

/// <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;
}

叶子 2007-09-14
  • 打赏
  • 举报
回复
直接操作文件流---加密:

程序代码:

/// <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)
{
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);
}
}

叶子 2007-09-14
  • 打赏
  • 举报
回复
//名称空间
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());
}
试试行不行!

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧