要解密的数据的长度无效

wyman25 2008-10-03 03:09:56
这是一个使用DES进行文件加密的类,只有两个方法,一个是加密方法:public void Encrypt(string FileName),另一个是解密方法:public void Decrypt(string FileName),能进行加密,但解密时候出现错误,错误信息为:要解密的数据的长度无效。
请高手赐教!
class DESCrypt
{
private string Key = "12345678";
public void Encrypt(string FileName)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
des.Key = ASCIIEncoding.Default.GetBytes(Key);
des.IV = ASCIIEncoding.Default.GetBytes(Key);
FileStream InputFileStream = File.OpenRead(FileName);
byte[] FileStreamArray = new byte[InputFileStream.Length-1];
InputFileStream.Read(FileStreamArray, 0, FileStreamArray.Length);
InputFileStream.Close();
MemoryStream ms = new MemoryStream();
CryptoStream FileCryptoStream = new CryptoStream(ms,des.CreateEncryptor(), CryptoStreamMode.Write);
FileCryptoStream.Write(FileStreamArray, 0, FileStreamArray.Length);
FileCryptoStream.FlushFinalBlock();
InputFileStream = File.OpenWrite(FileName);
foreach (byte b in ms.ToArray())
{
InputFileStream.WriteByte(b);

}
ms.Close();
InputFileStream.Close();
FileCryptoStream.Close();
}
public void Decrypt(string FileName)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
des.Key = ASCIIEncoding.Default.GetBytes(Key);
des.IV = ASCIIEncoding.Default.GetBytes(Key);
FileStream InputFileStream = File.OpenRead(FileName);
byte[] FileStreamArray = new byte[InputFileStream.Length - 1];
InputFileStream.Read(FileStreamArray, 0, FileStreamArray.Length);
InputFileStream.Close();
MemoryStream ms = new MemoryStream();
CryptoStream FileCryptoStream = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
FileCryptoStream.Write(FileStreamArray, 0, FileStreamArray.Length);
FileCryptoStream.FlushFinalBlock();
InputFileStream = File.OpenWrite(FileName);
foreach (byte b in ms.ToArray())
{
InputFileStream.WriteByte(b);

}
ms.Close();
InputFileStream.Close();
FileCryptoStream.Close();
}
}
...全文
1858 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
lihaoran4628513 2011-11-14
  • 打赏
  • 举报
回复
结贴了
boois 2011-10-11
  • 打赏
  • 举报
回复
4楼的方法是正确的,关键是byte[]和String的无损转换问题
Luckyboys 2008-10-03
  • 打赏
  • 举报
回复
还有就是,你那个解密的File.OpenWrite( FileName );是不能够覆盖完全的

所以顺便把你的类改了一下写入文件和读取密文的地方

class DESCrypt
{
private string Key = "12345678";
public void Encrypt( string FileName )
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
des.Key = ASCIIEncoding.Default.GetBytes( Key );
des.IV = ASCIIEncoding.Default.GetBytes( Key );

FileStream InputFileStream = File.OpenRead( FileName );
byte[] FileStreamArray = new byte[InputFileStream.Length];

InputFileStream.Read( FileStreamArray , 0 , FileStreamArray.Length );
InputFileStream.Close();

MemoryStream ms = new MemoryStream();
CryptoStream FileCryptoStream = new CryptoStream( ms , des.CreateEncryptor() , CryptoStreamMode.Write );
FileCryptoStream.Write( FileStreamArray , 0 , FileStreamArray.Length );
FileCryptoStream.Close();

InputFileStream = File.OpenWrite( FileName );

foreach( byte b in ms.ToArray() )
{
InputFileStream.WriteByte( b );
}
ms.Close();
InputFileStream.Close();
}

public void Decrypt( string FileName )
{
//生成Provider并设置钥匙
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
des.Key = ASCIIEncoding.Default.GetBytes( Key );
des.IV = ASCIIEncoding.Default.GetBytes( Key );

//读取已加密数据
StreamReader reader = new StreamReader( FileName );
byte[] FileStreamArray = new byte[reader.BaseStream.Length];

reader.BaseStream.Read( FileStreamArray , 0 , FileStreamArray.Length );
reader.Close();

//生成解密流
MemoryStream ms = new MemoryStream( FileStreamArray );
CryptoStream FileCryptoStream = new CryptoStream( ms , des.CreateDecryptor() , CryptoStreamMode.Read );

//读取解密了的数据,并写入原来的文件
BinaryReader br = new BinaryReader( FileCryptoStream );
FileStreamArray = new byte[1000];

BinaryWriter bw = new BinaryWriter( new StreamWriter( FileName ).BaseStream );
int iReadLength;//读取了多长
while( ( iReadLength = br.Read( FileStreamArray , 0 , 1000 ) ) > 0 )
{
bw.Write( FileStreamArray , 0 , iReadLength );
}

//关闭
bw.Close();
FileCryptoStream.Close();
ms.Close();
}
}
行者无疆-Kevin 2008-10-03
  • 打赏
  • 举报
回复
是你加密后的字符串更改过了,你再解密就会出错.
可以调试对比一下
sxmonsy 2008-10-03
  • 打赏
  • 举报
回复
问题解决了?我来接分
wyman25 2008-10-03
  • 打赏
  • 举报
回复
啊,真是的,原来就错在-1,原本代码有些地方是复制别人的,加上对数组的创建时候对“下标从0开始”这点上有点模糊,所以就搞错了。大哥谢谢了!
阿云ivan 2008-10-03
  • 打赏
  • 举报
回复
试一下我的方法:

 public string Encrypt(string stringToEncrypt, string sKey)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
byte[] inputByteArray = Encoding.GetEncoding("UTF-8").GetBytes(stringToEncrypt);
des.Key = ASCIIEncoding.UTF8.GetBytes(sKey);
des.IV = ASCIIEncoding.UTF8.GetBytes(sKey);
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();
}

public string Decrypt(string stringToDecrypt, string sKey)
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();

byte[] inputByteArray = new byte[stringToDecrypt.Length / 2];
for (int x = 0; x < stringToDecrypt.Length / 2; x++)
{
int i = (Convert.ToInt32(stringToDecrypt.Substring(x * 2, 2), 16));
inputByteArray[x] = (byte)i;
}

des.Key = ASCIIEncoding.UTF8.GetBytes(sKey);
des.IV = ASCIIEncoding.UTF8.GetBytes(sKey);
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());
}
Luckyboys 2008-10-03
  • 打赏
  • 举报
回复
我也在试,首先我发现一个问题就是那个byte[]的数组初始化的时候,我不明白楼主为什么要-1
我把-1去掉了就会正常
但后面会出现一个字符串,而这个字符串在加密后和解密后都是会跟在结尾的(同样的值)
wyman25 2008-10-03
  • 打赏
  • 举报
回复
我手头上这些算法也大把大把的,我不是要算法,是想弄清楚为什么会这样,问题出在哪儿了。
狂顶!
周公 2008-10-03
  • 打赏
  • 举报
回复
using System;
using System.Security.Cryptography;
using System.Text;
using System.IO;

namespace Common
...{
/**//// <summary>
/// DESEncrypt加密解密算法。
/// </summary>
public sealed class DESEncrypt
...{
private DESEncrypt()
...{
//
// TODO: 在此处添加构造函数逻辑
//
}

private static string key = "zhoufoxcn";

/**//// <summary>
/// 对称加密解密的密钥
/// </summary>
public static string Key
...{
get
...{
return key;
}
set
...{
key = value;
}
}

/**//// <summary>
/// DES加密
/// </summary>
/// <param name="encryptString"></param>
/// <returns></returns>
public static string DesEncrypt(string encryptString)
...{
byte[] keyBytes = Encoding.UTF8.GetBytes(key.Substring(0, 8));
byte[] keyIV = keyBytes;
byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
MemoryStream mStream = new MemoryStream();
CryptoStream cStream = new CryptoStream(mStream, provider.CreateEncryptor(keyBytes, keyIV), CryptoStreamMode.Write);
cStream.Write(inputByteArray, 0, inputByteArray.Length);
cStream.FlushFinalBlock();
return Convert.ToBase64String(mStream.ToArray());
}

/**//// <summary>
/// DES解密
/// </summary>
/// <param name="decryptString"></param>
/// <returns></returns>
public static string DesDecrypt(string decryptString)
...{
byte[] keyBytes = Encoding.UTF8.GetBytes(key.Substring(0, 8));
byte[] keyIV = keyBytes;
byte[] inputByteArray = Convert.FromBase64String(decryptString);
DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
MemoryStream mStream = new MemoryStream();
CryptoStream cStream = new CryptoStream(mStream, provider.CreateDecryptor(keyBytes, keyIV), CryptoStreamMode.Write);
cStream.Write(inputByteArray, 0, inputByteArray.Length);
cStream.FlushFinalBlock();
return Encoding.UTF8.GetString(mStream.ToArray());
}
}
}

看看这个,我自己用的,也是我自己写的。

110,534

社区成员

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

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

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