我遇到以下问题:有一个名为UserConfigStorage
的类,其中有8个字符串。程序首次运行后,将要求用户输入其个人信息,并将这些信息存储在上述8个字符串中。用户单击按钮后,该类将被序列化和加密,以防止用户对其进行修改。然后,当程序第二次运行时,在Form_Load
事件中,文件被解密,并且文件中的信息使用反序列化方法加载到文本框。但是,会抛出一个异常System.Runtime.Serialization.SerializationException: End of Stream encountered before parsing was completed
,并且无法读取该文件。
查看代码和生成的文件时,我发现生成的解密文件没有全部信息。实际上,它只存储了8个字符串中的6个。
方法如下:
序列化方法
public void SerializeUserConfig(string fileName)
{
try
{
FileStream fileStream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
BinaryFormatter binForm = new BinaryFormatter();
binForm.Serialize(fileStream, userconfigstorage);
fileStream.Close();
encryptor.Encrypt(fileName, perfilAcesso.GetUserConfigPath() + "Encrypted", "syndra15OP");
File.Delete(fileName);
MessageBox.Show("Dados salvos com sucesso!");
}
catch (Exception exception)
{
errorlog.SetError(exception.ToString());
SerializeError(perfilAcesso.GetUserErrorLogPath());
MessageBox.Show("Houve um erro ao salvar as configurações!\nPor favor, contate o desenvolvedor.\n\nEID: 002");
}
}
反序列化方法
public UserConfigStorage DeserializeUserConfig(string fileName)
{
encryptor.Decrypt(perfilAcesso.GetUserConfigPath() + "Encrypted", fileName, "syndra15OP");
FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read);
BinaryFormatter binForm = new BinaryFormatter();
UserConfigStorage userconfigstorage = (UserConfigStorage)binForm.Deserialize(fileStream);
fileStream.Close();
return userconfigstorage;
}
加密方法(在Encryptor
类中)
public void Encrypt(string input, string output, string strHash)
{
FileStream inStream, outStream;
CryptoStream cryStream;
TripleDESCryptoServiceProvider tdc = new TripleDESCryptoServiceProvider();
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
byte[] byteHash, byteText;
inStream = new FileStream(input, FileMode.Open, FileAccess.Read);
outStream = new FileStream(output, FileMode.OpenOrCreate, FileAccess.Write);
byteHash = md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(strHash));
byteText = File.ReadAllBytes(input);
md5.Clear();
tdc.Key = byteHash;
tdc.Mode = CipherMode.ECB;
cryStream = new CryptoStream(outStream, tdc.CreateEncryptor(), CryptoStreamMode.Write);
int bytesRead;
long length, position = 0;
length = inStream.Length;
while (position < length)
{
bytesRead = inStream.Read(byteText, 0, byteText.Length);
position += bytesRead;
cryStream.Write(byteText, 0, bytesRead);
}
inStream.Close();
outStream.Close();
cryStream.Close();
}
解密方法
//The same as Encrypt(), except that for cryStream, it's tdc.CreateDecryptor()
要序列化的类
[Serializable()]
public class UserConfigStorage
{
// 8 strings here, all public, each with its public getter
}
请问有人导致文件无法完全解密的原因是什么? 预先感谢!
答案 0 :(得分:1)
是的,using绝对是您在这里的朋友! :)
为什么要将该对象序列化为文件,然后再将其加密为另一个文件?
我已经清理了一下您的代码,这应该可以正常工作:
public void SerializeUserConfig(string fileName)
{
try
{
Encrypt(userconfigstorage, Path.Combine(perfilAcesso.GetUserConfigPath(), fileName), "syndra15OP");
MessageBox.Show("Dados salvos com sucesso!");
}
catch (Exception exception)
{
errorlog.SetError(exception.ToString());
SerializeError(perfilAcesso.GetUserErrorLogPath());
MessageBox.Show("Houve um erro ao salvar as configurações!\nPor favor, contate o desenvolvedor.\n\nEID: 002");
}
}
public UserConfigStorage DeserializeUserConfig(string fileName)
{
return Decrypt(Path.Combine(perfilAcesso.GetUserConfigPath(), fileName), "syndra15OP");
}
public void Encrypt(UserConfigStorage input, string filePath, string strHash)
{
using (TripleDESCryptoServiceProvider tdc = new TripleDESCryptoServiceProvider())
{
using (FileStream outStream = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write))
{
using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider())
{
tdc.Key = md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(strHash));
md5.Clear();
}
tdc.Mode = CipherMode.ECB;
using (CryptoStream cryStream = new CryptoStream(outStream, tdc.CreateEncryptor(), CryptoStreamMode.Write))
{
BinaryFormatter binForm = new BinaryFormatter();
binForm.Serialize(cryStream, input);
}
}
}
}
public UserConfigStorage Decrypt(string filePath, string strHash)
{
UserConfigStorage output;
using (TripleDESCryptoServiceProvider tdc = new TripleDESCryptoServiceProvider())
{
using (FileStream outStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider())
{
tdc.Key = md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(strHash));
md5.Clear();
}
tdc.Mode = CipherMode.ECB;
using (CryptoStream cryStream = new CryptoStream(outStream, tdc.CreateDecryptor(), CryptoStreamMode.Read))
{
BinaryFormatter binForm = new BinaryFormatter();
output = binForm.Deserialize(cryStream) as UserConfigStorage;
}
}
}
return output;
}
致谢