C# 如何仅对文件的前几个字节进行加密/解密(其余字节应未加密)?

C# 如何仅对文件的前几个字节进行加密/解密(其余字节应未加密)?,c#,encryption,cryptography,byte,C#,Encryption,Cryptography,Byte,因此,我在C#加密/解密算法中实现了加密/解密算法,它在加密/解密任何文件时都能很好地工作。 我现在的问题是,如何只加密(然后解密)文件的前几个(兆)字节 例如:我有一个2GB的文件,我只想加密这个文件的3MB 我试过一些方法,但都没有达到我想要的效果。我已经尝试计算读取的字节数,如果读取的字节数超过了限制(3MB),则停止加密,继续将正常(未加密的数据)写入文件。但在解密后,出现了“填充”异常,等等。另一个例子:我(使用此方法)“成功”加密了50kb.txt文件中的20kb,但在解密后,.tx

因此,我在C#加密/解密算法中实现了加密/解密算法,它在加密/解密任何文件时都能很好地工作。 我现在的问题是,如何只加密(然后解密)文件的前几个(兆)字节

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

我试过一些方法,但都没有达到我想要的效果。我已经尝试计算读取的字节数,如果读取的字节数超过了限制(3MB),则停止加密,继续将正常(未加密的数据)写入文件。但在解密后,出现了“填充”异常,等等。另一个例子:我(使用此方法)“成功”加密了50kb.txt文件中的20kb,但在解密后,.txt文件中的最后一行仍然有一些“奇怪”字符-因此这不起作用(如果我想要加密图像,则解密后仍然“损坏”)

对于加密,我使用此函数:

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;
}
}
publicstaticbool加密(stringinputfilepath、stringoutputfilepath、stringencryptionkey)
{
尝试
{
使用(FileStream fsInput=newfilestream(inputFilePath,FileMode.Open))
{
使用(FileStream fsOutput=newfilestream(outputfilePath,FileMode.Create))
{
fsInput.Position=0;
使用(Aes encryptor=Aes.Create())
{
Rfc2898DeriveBytes pdb=新的Rfc2898DeriveBytes(加密密钥,新字节[]{0x49,0x76,0x61,0x6e,0x20,0x4d,0x65,0x64,0x76,0x65,0x64,0x76});
encryptor.Key=pdb.GetBytes(32);
encryptor.IV=pdb.GetBytes(16);
使用(CryptoStream cs=new CryptoStream(fsOutput,encryptor.CreateEncryptor(),CryptoStreamMode.Write))
{
int bufferLen=4096;
byte[]buffer=新字节[bufferLen];
int字节读取;
int字节写计数器=0;
做
{
bytesRead=fsInput.Read(buffer,0,bufferLen);
//我的方法

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

  • 将前4个字节读取为整数
  • 读取加密流的字节数与整数表示的字节数相同
  • 解密并不写入新文件
  • 将未更改的字节从部分加密的文件压缩到新的完全解密的文件

  • 顺便说一句,20000字节!=20KB.Uhm..我想每个人都会知道我的意思。在这个代码示例中,我不需要像您所看到的那样在任何地方都完全相等。