如何加密/解密文件的前几个字节(其余应该是未加密)? [英] How to encrypt / decrypt only first few bytes of a file (the rest should be unencrypted)?

查看:347
本文介绍了如何加密/解密文件的前几个字节(其余应该是未加密)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我已经实现在C#加密/解密算法,当加密/解密任何文件时工作完美。
现在我的问题是,我如何加密(然后Decrypt)只有文件的前几个(兆)字节。

So, I have implemented in C# Encryption / Decryption algorithm which works perfectly fine when Encrypting / Decrypting any file. And my question now is, how can I Encrypt (then Decrypt) only first few (mega)bytes of a file.

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

For example: I have a 2GB file and I want to encrypt only 3MB of this file.

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

I have tried some things, but nothing worked as I wanted to. I have tried to count readed bytes and if readed bytes are over the limit (3MB) then stop encrypting and just continue to write normal (unecrypted data) to file. But after decryption, the "padding" exception appeared, etc. Another example: I had (with this method) "successfully" encrypted 20kb of a 50kb .txt file, but after decryption, the last line in .txt file had still some "strange" charachters - so this is not working (If i want for exaple encrypted image - is still after decryption "damaged").

function:

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。为此,您基本上需要读取块中的文件,如下所示:

To achieve this you need to know exactly how many bytes are in the encrypted stream. You can easily write integer, which is 4 bytes, before writing encrypted stream to your new partially encrypted file. Then, when you decrypt the file you read first 4 bytes, and you know exactly how many bytes to read with your CryptoStream. For this you basically need to read files in chunks as follows:


  1. 首先读取4个字节作为整数

  2. 读取加密流中与整数一样多的字节

  3. 解密并且不写入新文件

  4. 将部分加密文件完全解密的档案

  1. read first 4 bytes as integer
  2. read encrypted stream as many bytes as your integer says
  3. decrypt and write no new file
  4. pump bytes unchanged from partially encrypted file to a new fully decrypted file

这篇关于如何加密/解密文件的前几个字节(其余应该是未加密)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆