我有这个代码,用于解密文件,但如果我运行它,它会在using语句结束时抛出CryptographicException(要解密的数据的长度无效) using (CryptoStream ...) { ... }
public static void DecryptFile(string path, string key, string saltkey, string ivkey)
{
try
{
byte[] cipherTextBytes;
using (StreamReader reader = new StreamReader(path)) cipherTextBytes = Encoding.UTF8.GetBytes(reader.ReadToEnd());
byte[] keyBytes = new Rfc2898DeriveBytes(key, Encoding.ASCII.GetBytes(saltkey)).GetBytes(256 / 8);
RijndaelManaged symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.None };
ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, Encoding.ASCII.GetBytes(ivkey));
byte[] plainTextBytes;
using (MemoryStream memoryStream = new MemoryStream(cipherTextBytes))
{
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
{
plainTextBytes = new byte[Encoding.UTF8.GetByteCount((new StreamReader(cryptoStream)).ReadToEnd())];
cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
//plainTextBytes = memoryStream.ToArray();
cryptoStream.FlushFinalBlock();
}
}
string result = Encoding.ASCII.GetString(plainTextBytes, 0, plainTextBytes.Length).TrimEnd("\0".ToCharArray());
using (FileStream writer = new FileStream(path, FileMode.Create)) writer.Write(Encoding.ASCII.GetBytes(result), 0, Encoding.ASCII.GetBytes(result).Length);
MessageBox.Show("Decrypt succesfull");
}
catch (Exception ex)
{
MessageBox.Show("An error while decrypting the file:\n\n" + ex, "Error");
}
}
}
Run Code Online (Sandbox Code Playgroud)
有谁知道这是为什么或我如何解决它?(我不知道它是否来自我的加密方法,但我有另一个程序使用完全相同的东西来加密字符串,并且确实有效.)
我的加密方法:
public static void EncryptFile(string path, string key, string saltkey, string ivkey)
{
try
{
byte[] TextBytes;
using (StreamReader reader = new StreamReader(path)) TextBytes = Encoding.UTF8.GetBytes(reader.ReadToEnd());
byte[] KeyBytes = new Rfc2898DeriveBytes(key, Encoding.ASCII.GetBytes(saltkey)).GetBytes(256 / 8);
RijndaelManaged symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding = PaddingMode.Zeros };
ICryptoTransform encryptor = symmetricKey.CreateEncryptor(KeyBytes, Encoding.ASCII.GetBytes(ivkey));
byte[] CipherTextBytes;
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
cs.Write(TextBytes, 0, TextBytes.Length);
cs.FlushFinalBlock();
CipherTextBytes = ms.ToArray();
}
}
using (FileStream writer = new FileStream(path, FileMode.Create)) writer.Write(CipherTextBytes, 0, CipherTextBytes.Length);
MessageBox.Show("Encrypt succesfull");
}
catch (Exception ex)
{
MessageBox.Show("An error while encrypting the file:\n\n" + ex, "Error");
}
}
Run Code Online (Sandbox Code Playgroud)
Wol*_*yrd 14
您的代码存在一些问题:
您使用加密中的零填充模式和解密中的无填充模式.这些需要匹配
您使用Encoding.UTF8从文件加载字节,您需要读取原始字节,您可以通过使用以下代码来执行此操作:
byte [] cipherTextBytes = File.ReadAllBytes(path);
cryptoStream.FlushFinalBlock();只使用流的单次迭代时调用.如果您只进行单个块迭代,则在Decrypt中不需要此调用.
您以UTF8格式从文件中读取原始文本,然后将其写回ASCII.您应该在decrypt中更改结果分配以使用UTF8或(最好)更改两者以使用原始字节.
在就地覆盖时,使用"创建"与文件进行交互.如果您知道该文件已经存在(当您替换它时),您应该使用truncate或更好,但只需调用File.WriteAllBytes.
你的解密是各种搞砸了.看起来你正在将自己绑在字节检索的结上.您应该只使用CryptoStream中的原始字节,而不是尝试使用UTF8
这是一套经过修改的方法:
public static void DecryptFile(string path, string key, string saltkey, string ivkey)
{
byte[] cipherTextBytes = File.ReadAllBytes(path);
byte[] keyBytes = new Rfc2898DeriveBytes(key, Encoding.ASCII.GetBytes(saltkey)).GetBytes(256 / 8);
RijndaelManaged symmetricKey = new RijndaelManaged() { Mode = CipherMode.CFB, Padding = PaddingMode.PKCS7 };
ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, Encoding.ASCII.GetBytes(ivkey));
byte[] plainTextBytes;
const int chunkSize = 64;
using (MemoryStream memoryStream = new MemoryStream(cipherTextBytes))
using (MemoryStream dataOut = new MemoryStream())
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
using (var decryptedData = new BinaryReader(cryptoStream))
{
byte[] buffer = new byte[chunkSize];
int count;
while ((count = decryptedData.Read(buffer, 0, buffer.Length)) != 0)
dataOut.Write(buffer, 0, count);
plainTextBytes = dataOut.ToArray();
}
File.WriteAllBytes(path, plainTextBytes);
}
Run Code Online (Sandbox Code Playgroud)
和:
public static void EncryptFile(string path, string key, string saltkey, string ivkey)
{
byte[] TextBytes = File.ReadAllBytes(path);
byte[] KeyBytes = new Rfc2898DeriveBytes(key, Encoding.ASCII.GetBytes(saltkey)).GetBytes(256 / 8);
RijndaelManaged symmetricKey = new RijndaelManaged() { Mode = CipherMode.CFB, Padding = PaddingMode.PKCS7 };
ICryptoTransform encryptor = symmetricKey.CreateEncryptor(KeyBytes, Encoding.ASCII.GetBytes(ivkey));
byte[] CipherTextBytes;
using (MemoryStream ms = new MemoryStream())
using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
cs.Write(TextBytes, 0, TextBytes.Length);
cs.FlushFinalBlock();
CipherTextBytes = ms.ToArray();
}
File.WriteAllBytes(path, CipherTextBytes);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17371 次 |
| 最近记录: |