嗨,我正在使用C#代码并尝试加密和解密CSV文件 缺少记录和24列。
将其逐块加密4 mb,并随机生成盐。我该如何解决这个问题。
class Program
{
public static void Main()
{
Program p = new Program();
string In_filePath = @"C:\Users\Selvakumar.Velusamy\Desktop\Test\Check.csv";
string Enc_Out_filePath = @"C:\Users\Selvakumar.Velusamy\Desktop\Test\Check_Enc.csv";
string Dec_Out_filePath = @"C:\Users\Selvakumar.Velusamy\Desktop\Test\Check_Dec.csv";
byte[] password = Encoding.ASCII.GetBytes("Test");
p.Encrypt(In_filePath,Enc_Out_filePath, password);
p.Decrypt(password , Enc_Out_filePath, Dec_Out_filePath);
}
public static byte[] GenerateRandomSalt()
{
byte[] data = new byte[32];
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
for (int i = 0; i < 10; i++)
{
rng.GetBytes(data);
}
}
return data;
}
public void Encrypt(string inputFileName, string outputFileName, byte[] encryptionKey)
{
byte[] salt = GenerateRandomSalt();
int chunkSizeInBytes = 4 * 1048576;
byte[] chunk = new byte[chunkSizeInBytes];
FileStream Infs = new FileStream(inputFileName, FileMode.Open);
FileStream OutFs = new FileStream(outputFileName, FileMode.Create);
using (var aesProvider = new RijndaelManaged())
{
aesProvider.KeySize = 256;
aesProvider.BlockSize = 128;
aesProvider.Padding = PaddingMode.PKCS7;
aesProvider.Mode = CipherMode.CFB;
using (var key = new Rfc2898DeriveBytes(encryptionKey, salt, 50000))
{
aesProvider.Key = key.GetBytes(aesProvider.KeySize / 8);
aesProvider.IV = key.GetBytes(aesProvider.BlockSize / 8);
int bytesRead;
MemoryStream mstream = null;
try
{
mstream = new MemoryStream();
mstream.Write(salt, 0, salt.Length);
while ((bytesRead = Infs.Read(chunk, 0, chunkSizeInBytes)) > 0)
{
using (var cryptoStream = new CryptoStream(mstream, aesProvider.CreateEncryptor(), CryptoStreamMode.Write))
{
cryptoStream.Write(chunk, 0, bytesRead);
OutFs.Write(mstream.ToArray(), 0, mstream.ToArray().Length);
}
mstream = new MemoryStream();
}
}
catch (Exception)
{
throw;
}
finally
{
if (mstream != null)
mstream.Close();
if (Infs != null)
Infs.Dispose();
if (OutFs != null)
OutFs.Dispose();
Infs.Close();
OutFs.Close();
}
}
}
}
public void Decrypt(byte[] password, string inputfile, string outputfile)
{
byte[] salt = new byte[32];
FileStream fsCrypt = new FileStream(inputfile, FileMode.Open);
int readsize = fsCrypt.Read(salt, 0, salt.Length);
RijndaelManaged AES = new RijndaelManaged();
AES.KeySize = 256;
AES.BlockSize = 128;
var key = new Rfc2898DeriveBytes(password, salt, 50000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
AES.Padding = PaddingMode.None;
AES.Mode = CipherMode.CFB;
FileStream fsOut = new FileStream(outputfile, FileMode.Create);
int read;
byte[] buffer = new byte[1048576 * 4];
MemoryStream ms;
try
{
while ((read = fsCrypt.Read(buffer, 0, (buffer.Length))) > 0)
{
ms = new MemoryStream(buffer);
using (CryptoStream cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Read))
{
int chunkCount = cs.Read(buffer, 0, read);
fsOut.Write(buffer, 0, buffer.Length);
fsCrypt.Read(salt, 0, salt.Length);
}
ms = new MemoryStream();
}
}
catch (CryptographicException ex_CryptographicException)
{
Debug.WriteLine("CryptographicException error: " + ex_CryptographicException.Message);
}
catch (Exception ex)
{
Debug.WriteLine("Error: " + ex.Message);
}
finally
{
fsOut.Close();
fsCrypt.Close();
}
}
}
逐块加密csv文件并将其解密,我得到的结果是错误的csv。每个块后面都有一些垃圾字符。
谢谢。
答案 0 :(得分:0)
您在流的开头编写了一次盐,但是对于每个块都读取了盐。
像这样更改您的加密方法:
....
MemoryStream mstream = null;
try {
while ((bytesRead = Infs.Read(chunk, 0, chunkSizeInBytes)) > 0) {
mstream = new MemoryStream();
mstream.Write(salt, 0, salt.Length);
using (var cryptoStream = new CryptoStream(mstream, aesProvider.CreateEncryptor(), CryptoStreamMode.Write)) {
....
或删除Decrypt方法的while循环内的fsCrypt.Read(salt, 0, salt.Length);
。