如何仅加密/解密文件的前几个字节(其余的应未加密)

本文关键字:加密 字节 几个 何仅 文件 解密 | 更新日期: 2023-09-27 18:37:18

所以,我已经实现了C#加密/解密算法,它在加密/解密任何文件时工作得很好。我现在的问题是,我如何才能只加密(然后解密)文件的前几个(兆)字节。

例如:我有一个 2GB 的文件,我只想加密这个文件的 3MB。

我已经尝试了一些事情,但没有像我想要的那样工作。我尝试计算读取的字节数,如果读取的字节数超过限制(3MB),则停止加密并继续将正常(未加密的数据)写入文件。但是解密后,出现了"填充"异常,等等。另一个例子:我(使用这种方法)"成功"加密了 20kb 的 50kb .txt文件,但解密后,.txt文件的最后一行仍然有一些"奇怪"字符 - 所以这是行不通的(如果我想要 exaple 加密图像 - 解密后仍然"损坏")。

对于加密,我使用此功能:

public static bool Encrypt(string inputFilePath, string outputfilePath, string EncryptionKey)
{
try
{
    using (FileStream fsInput = new FileStream(inputFilePath, FileMode.Open))
    {
        using (FileStream fsOutput = new FileStream(outputfilePath, FileMode.Create))
        {
            fsInput.Position = 0;                       
            using (Aes encryptor = Aes.Create())
            {
                Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
                encryptor.Key = pdb.GetBytes(32);
                encryptor.IV = pdb.GetBytes(16);
                using (CryptoStream cs = new CryptoStream(fsOutput, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    int bufferLen = 4096;
                    byte[] buffer = new byte[bufferLen];
                    int bytesRead;
                    int byteWriteCounter = 0;                           
                    do
                    {
                        bytesRead = fsInput.Read(buffer, 0, bufferLen);
                        //my method
                        if(byteWriteCounter <= 20000){ //if readed bytes <= 20kb
                            cs.Write(buffer, 0, bytesRead); // then encrypt 
                        }else{ // if bytes are over 20kb
                            fsOutput.Write(buffer, 0, bytesRead); //write normal (unecrypted)
                        }                           
                        byteWriteCounter += bytesRead;

                    } while (bytesRead != 0);
                    return true;
                }
            }
        }
    }
}
catch (SystemException se)
{
    Console.WriteLine(se);
    return false;
}
}

对于解密(我使用)是类似的功能/方法:

public static bool Decrypt(string inputFilePath, string outputfilePath, string EncryptionKey)
{
try
{
    using (FileStream fsInput = new FileStream(inputFilePath, FileMode.Open))
    {

        using (Aes encryptor = Aes.Create())
        {
            Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
            encryptor.Key = pdb.GetBytes(32);
            encryptor.IV = pdb.GetBytes(16);
            using (FileStream fsOutput = new FileStream(outputfilePath, FileMode.Create))
            {
                using (CryptoStream cs = new CryptoStream(fsOutput, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    int bufferLen = 4096;
                    byte[] buffer = new byte[bufferLen];
                    int bytesRead;
                    int byteWriteCounter = 0;
                    do
                    {
                        bytesRead = fsInput.Read(buffer, 0, bufferLen);
                        //my method
                        if(byteWriteCounter <= 20000){ //if readed bytes <= 20kb
                            cs.Write(buffer, 0, bytesRead); // then decrypt 
                        }else{ // if bytes are over 20kb
                            fsOutput.Write(buffer, 0, bytesRead); //write normal data
                        }
                        byteWriteCounter += bytesRead;
                    } while (bytesRead != 0);
                }
            }
        }                   
    }
    return true;
}
catch (SystemException s)
{
    Console.WriteLine(s);
    return false;
}
}

如何仅加密/解密文件的前几个字节(其余的应未加密)

要实现这一点,您需要确切地知道加密流中有多少字节。在将加密流写入新的部分加密文件之前,您可以轻松地写入整数(即 4 个字节)。然后,当您解密文件时,您会读取前 4 个字节,并且您确切地知道要使用 CryptoStream 读取多少字节。为此,您基本上需要按如下方式读取块中的文件:

  1. 将前 4 个字节读取为整数
  2. 读取加密流的字节数与整数所说的字节数一样多
  3. 解密和写入无新文件
  4. 将字节数从部分加密文件泵到新的完全解密文件