none
Как зашифровать и расшифровать файл с помощью C# RRS feed

  • Вопрос

  • Как зашифровать и расшифровать файл с помощью C# ? Причём чтобы получилось зашифровать не только текстовый документ, но и картинку, программу. После шифрования по уже созданной тут теме, у изображения или программы просто слетает кодировка некоторых символов и изображение/программу уже нельзя запустить.
    1 июня 2016 г. 20:55

Ответы

  • Вдумчиво посмотрел на пример, жесть какая-то. Вот так все работает:

    namespace CSEncryptDecrypt
    {
        class Class1
        {
            //  Call this function to remove the key from memory after use for security
            [System.Runtime.InteropServices.DllImport("KERNEL32.DLL", EntryPoint = "RtlZeroMemory")]
            public static extern bool ZeroMemory(IntPtr Destination, int Length);
    
            // Function to Generate a 64 bits Key.
            static DESCryptoServiceProvider GenerateKey()
            {
                // Create an instance of Symetric Algorithm. Key and IV is generated automatically.
                DESCryptoServiceProvider desCrypto = (DESCryptoServiceProvider)DESCryptoServiceProvider.Create();
    
                // Use the Automatically generated key for Encryption. 
                return desCrypto;
            }
    
            static void EncryptFile(string sInputFilename,
               string sOutputFilename,
              DESCryptoServiceProvider sKey)
            {
                FileStream fsInput = new FileStream(sInputFilename,
                   FileMode.Open,
                   FileAccess.Read);
    
                FileStream fsEncrypted = new FileStream(sOutputFilename,
                   FileMode.Create,
                   FileAccess.Write);
                DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
                DES.Key = sKey.Key;
                DES.IV = sKey.IV;
                ICryptoTransform desencrypt = DES.CreateEncryptor();
                CryptoStream cryptostream = new CryptoStream(fsEncrypted,
                   desencrypt,
                   CryptoStreamMode.Write);
    
                byte[] bytearrayinput = new byte[fsInput.Length];
                fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
                cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
                cryptostream.Close();
                fsInput.Close();
                fsEncrypted.Close();
            }
    
            static void DecryptFile(string sInputFilename,
               string sOutputFilename,
               DESCryptoServiceProvider sKey)
            {
                DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
                //A 64 bit key and IV is required for this provider.
                //Set secret key For DES algorithm.
                DES.Key = sKey.Key;
                //Set initialization vector.
                DES.IV = sKey.IV;
    
                //Create a file stream to read the encrypted file back.
                FileStream fsread = new FileStream(sInputFilename,
                   FileMode.Open,
                   FileAccess.Read);
                //Create a DES decryptor from the DES instance.
                ICryptoTransform desdecrypt = DES.CreateDecryptor();
                //Create crypto stream set to read and do a 
                //DES decryption transform on incoming bytes.
                CryptoStream cryptostreamDecr = new CryptoStream(fsread,
                   desdecrypt,
                   CryptoStreamMode.Read);
                //Print the contents of the decrypted file.
                FileStream fsDecrypted = new FileStream(sOutputFilename, FileMode.Create);
                byte[] bytearrayinput = new byte[1024];
                int length;
                do
                {
                    length = cryptostreamDecr.Read(bytearrayinput, 0, 1024);
                    fsDecrypted.Write(bytearrayinput, 0, length);
                } while (length == 1024);            
                fsDecrypted.Flush();
                fsDecrypted.Close();
            }
    
            static void Main()
            {
                // Must be 64 bits, 8 bytes.
                // Distribute this key to the user who will decrypt this file.
                DESCryptoServiceProvider sSecretKey;
    
                // Get the Key for the file to Encrypt.
                sSecretKey = GenerateKey();
    
                // For additional security Pin the key.
                GCHandle gch = GCHandle.Alloc(sSecretKey.Key, GCHandleType.Pinned);
    
                // Encrypt the file.        
                EncryptFile(@"d:\MyData.txt",
                   @"d:\Encrypted.txt",
                   sSecretKey);
    
                // Decrypt the file.
                DecryptFile(@"d:\Encrypted.txt",
                   @"d:\Decrypted.txt",
                   sSecretKey);
    
                gch.Free();
            }
        }
    }

    • Помечено в качестве ответа Mikha_Mikhin 3 июня 2016 г. 8:39
    2 июня 2016 г. 11:47
    Отвечающий
  • Можно и как в примере, только обе части ключа надо
    • Помечено в качестве ответа Mikha_Mikhin 3 июня 2016 г. 18:29
    Отвечающий

Все ответы

  • После шифрования файл становится зашифрованным. По этой причине содержимое файла становится недоступным. То есть если это программа, то ее нельзя запустить, если это картинка то ее нельзя посмотреть, если это текст то его нельзя прочитать. Именно для этого "нельзя" и делается шифрование.

    По вашему же описанию все работает совершенно правильно - программу не запустить, у текста "слетела кодировка" (на деле, конечно, все символы стали совсем другими после шифрования, никакого отношения к кодировке это не имеет).

    Если вы думайте что должно быть как то иначе, то возможно вы не совсем понимайте суть шифрования? Или вам нужно не шифрование файлов, а шифрование файловой системы когда файл автоматически шифруется при записи и дешифруется при чтении?



    This posting is provided "AS IS" with no warranties, and confers no rights.

    Модератор
  • После шифрования файл становится зашифрованным. По этой причине содержимое файла становится недоступным. То есть если это программа, то ее нельзя запустить, если это картинка то ее нельзя посмотреть, если это текст то его нельзя прочитать. Именно для этого "нельзя" и делается шифрование.

    По вашему же описанию все работает совершенно правильно - программу не запустить, у текста "слетела кодировка" (на деле, конечно, все символы стали совсем другими после шифрования, никакого отношения к кодировке это не имеет).

    Если вы думайте что должно быть как то иначе, то возможно вы не совсем понимайте суть шифрования? Или вам нужно не шифрование файлов, а шифрование файловой системы когда файл автоматически шифруется при записи и дешифруется при чтении?


    This posting is provided "AS IS" with no warranties, and confers no rights.



    Так трудно понять, что я имел в виду после шифровки и дешифровки?
    Сейчас покажу это на скриншоте на примере шифрования и дешифрования картинки:
    http://i.imgur.com/CJE4W67.png

    P.S. Картникой прям сюда выложить не получилось.
  • Просто у вас не получилось расшифровать файл. Если вы шифровали с помощью булевой алгебры, в какой то момент произошло переполнение, а соответственно и потеря данных, которая и не позволила вернутся к исходным значениям.
  • Добрый день.

    Судя по вашей картинке, у вас латинские буквы шифруются и дешифруются правильно. Остальные нет, так что, ищите или переполнение (как было сказано выше) или другую ошибку в алгоритме (не обязательно дешифрования, ошибка может быть и в алгоритме шифрования).

    Отвечающий
  • Просто у вас не получилось расшифровать файл. Если вы шифровали с помощью булевой алгебры, в какой то момент произошло переполнение, а соответственно и потеря данных, которая и не позволила вернутся к исходным значениям.

    Это весело, конечно, но как-то же должно быть возможно расшифровать без "переполнения и потери данных"?
  • Это весело, конечно, но как-то же должно быть возможно расшифровать без "переполнения и потери данных"?

    Конечно, найдите где у вас ошибка и исправьте ее. Тестировать в режиме отладки вы можете на файле из двух русских символов...
    Отвечающий
  • Ничего веселого в этом нет... Нужно брать отладчик и смотреть что получается... Я свой алгоритм шифрования дебажила около недели, пока нашла все глюки. Судя по картинки (если обе в одной кодировке) у вас все символы с кодом символа более 125 не пережили ваш алгоритм шифрования. Возможно ваш алгоритм шифрует с избытком, т.е. я имела в виду что размер выходного файла больше чем исходный, таким образом вам необходимо использовать два байта на один исходный байт. Не видя алгоритма трудно гадать, что приводит к переполнению.

  • Если вам станет вдруг лень изобретать велосипед или вам достаточно стандартных средств шифрования, то может вам стоит заглянуть сюда, вдруг это вам подойдет.
  • Конечно, найдите где у вас ошибка и исправьте ее. Тестировать в режиме отладки вы можете на файле из двух русских символов...
    https://support.microsoft.com/ru-ru/kb/307010

    Брал код отсюда. На текст он работает, на всё остальное - нет.
  • Конечно, найдите где у вас ошибка и исправьте ее. Тестировать в режиме отладки вы можете на файле из двух русских символов...

    https://support.microsoft.com/ru-ru/kb/307010

    Брал код отсюда. На текст он работает, на всё остальное - нет.
    Замените ASCIIEncoding.ASCII на UTF8 или unicode. Проблема в этом наверное.
  • Конечно, найдите где у вас ошибка и исправьте ее. Тестировать в режиме отладки вы можете на файле из двух русских символов...

    https://support.microsoft.com/ru-ru/kb/307010

    Брал код отсюда. На текст он работает, на всё остальное - нет.

    Замените ASCIIEncoding.ASCII на UTF8 или unicode. Проблема в этом наверное.

    Тоже самое. Вообще ничего не меняется.
  • А что должно поменяться? Возьмите файл из двух символов поставьте в код точку останова и выполняйте его по шагам. Смотрите как считается, нет ли переполнения или других ошибок.
    Отвечающий
  • А что должно поменяться? Возьмите файл из двух символов поставьте в код точку останова и выполняйте его по шагам. Смотрите как считается, нет ли переполнения или других ошибок.

    Программа никаких ошибок не пишет. Что я могу проверить этими паузами в коде?
  • Вдумчиво посмотрел на пример, жесть какая-то. Вот так все работает:

    namespace CSEncryptDecrypt
    {
        class Class1
        {
            //  Call this function to remove the key from memory after use for security
            [System.Runtime.InteropServices.DllImport("KERNEL32.DLL", EntryPoint = "RtlZeroMemory")]
            public static extern bool ZeroMemory(IntPtr Destination, int Length);
    
            // Function to Generate a 64 bits Key.
            static DESCryptoServiceProvider GenerateKey()
            {
                // Create an instance of Symetric Algorithm. Key and IV is generated automatically.
                DESCryptoServiceProvider desCrypto = (DESCryptoServiceProvider)DESCryptoServiceProvider.Create();
    
                // Use the Automatically generated key for Encryption. 
                return desCrypto;
            }
    
            static void EncryptFile(string sInputFilename,
               string sOutputFilename,
              DESCryptoServiceProvider sKey)
            {
                FileStream fsInput = new FileStream(sInputFilename,
                   FileMode.Open,
                   FileAccess.Read);
    
                FileStream fsEncrypted = new FileStream(sOutputFilename,
                   FileMode.Create,
                   FileAccess.Write);
                DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
                DES.Key = sKey.Key;
                DES.IV = sKey.IV;
                ICryptoTransform desencrypt = DES.CreateEncryptor();
                CryptoStream cryptostream = new CryptoStream(fsEncrypted,
                   desencrypt,
                   CryptoStreamMode.Write);
    
                byte[] bytearrayinput = new byte[fsInput.Length];
                fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
                cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
                cryptostream.Close();
                fsInput.Close();
                fsEncrypted.Close();
            }
    
            static void DecryptFile(string sInputFilename,
               string sOutputFilename,
               DESCryptoServiceProvider sKey)
            {
                DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
                //A 64 bit key and IV is required for this provider.
                //Set secret key For DES algorithm.
                DES.Key = sKey.Key;
                //Set initialization vector.
                DES.IV = sKey.IV;
    
                //Create a file stream to read the encrypted file back.
                FileStream fsread = new FileStream(sInputFilename,
                   FileMode.Open,
                   FileAccess.Read);
                //Create a DES decryptor from the DES instance.
                ICryptoTransform desdecrypt = DES.CreateDecryptor();
                //Create crypto stream set to read and do a 
                //DES decryption transform on incoming bytes.
                CryptoStream cryptostreamDecr = new CryptoStream(fsread,
                   desdecrypt,
                   CryptoStreamMode.Read);
                //Print the contents of the decrypted file.
                FileStream fsDecrypted = new FileStream(sOutputFilename, FileMode.Create);
                byte[] bytearrayinput = new byte[1024];
                int length;
                do
                {
                    length = cryptostreamDecr.Read(bytearrayinput, 0, 1024);
                    fsDecrypted.Write(bytearrayinput, 0, length);
                } while (length == 1024);            
                fsDecrypted.Flush();
                fsDecrypted.Close();
            }
    
            static void Main()
            {
                // Must be 64 bits, 8 bytes.
                // Distribute this key to the user who will decrypt this file.
                DESCryptoServiceProvider sSecretKey;
    
                // Get the Key for the file to Encrypt.
                sSecretKey = GenerateKey();
    
                // For additional security Pin the key.
                GCHandle gch = GCHandle.Alloc(sSecretKey.Key, GCHandleType.Pinned);
    
                // Encrypt the file.        
                EncryptFile(@"d:\MyData.txt",
                   @"d:\Encrypted.txt",
                   sSecretKey);
    
                // Decrypt the file.
                DecryptFile(@"d:\Encrypted.txt",
                   @"d:\Decrypted.txt",
                   sSecretKey);
    
                gch.Free();
            }
        }
    }

    • Помечено в качестве ответа Mikha_Mikhin 3 июня 2016 г. 8:39
    2 июня 2016 г. 11:47
    Отвечающий
  • Вдумчиво посмотрел на пример, жесть какая-то. Вот так все работает:

    namespace CSEncryptDecrypt
    {
        class Class1
        {
            //  Call this function to remove the key from memory after use for security
            [System.Runtime.InteropServices.DllImport("KERNEL32.DLL", EntryPoint = "RtlZeroMemory")]
            public static extern bool ZeroMemory(IntPtr Destination, int Length);
    
            // Function to Generate a 64 bits Key.
            static DESCryptoServiceProvider GenerateKey()
            {
                // Create an instance of Symetric Algorithm. Key and IV is generated automatically.
                DESCryptoServiceProvider desCrypto = (DESCryptoServiceProvider)DESCryptoServiceProvider.Create();
    
                // Use the Automatically generated key for Encryption. 
                return desCrypto;
            }
    
            static void EncryptFile(string sInputFilename,
               string sOutputFilename,
              DESCryptoServiceProvider sKey)
            {
                FileStream fsInput = new FileStream(sInputFilename,
                   FileMode.Open,
                   FileAccess.Read);
    
                FileStream fsEncrypted = new FileStream(sOutputFilename,
                   FileMode.Create,
                   FileAccess.Write);
                DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
                DES.Key = sKey.Key;
                DES.IV = sKey.IV;
                ICryptoTransform desencrypt = DES.CreateEncryptor();
                CryptoStream cryptostream = new CryptoStream(fsEncrypted,
                   desencrypt,
                   CryptoStreamMode.Write);
    
                byte[] bytearrayinput = new byte[fsInput.Length];
                fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
                cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
                cryptostream.Close();
                fsInput.Close();
                fsEncrypted.Close();
            }
    
            static void DecryptFile(string sInputFilename,
               string sOutputFilename,
               DESCryptoServiceProvider sKey)
            {
                DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
                //A 64 bit key and IV is required for this provider.
                //Set secret key For DES algorithm.
                DES.Key = sKey.Key;
                //Set initialization vector.
                DES.IV = sKey.IV;
    
                //Create a file stream to read the encrypted file back.
                FileStream fsread = new FileStream(sInputFilename,
                   FileMode.Open,
                   FileAccess.Read);
                //Create a DES decryptor from the DES instance.
                ICryptoTransform desdecrypt = DES.CreateDecryptor();
                //Create crypto stream set to read and do a 
                //DES decryption transform on incoming bytes.
                CryptoStream cryptostreamDecr = new CryptoStream(fsread,
                   desdecrypt,
                   CryptoStreamMode.Read);
                //Print the contents of the decrypted file.
                FileStream fsDecrypted = new FileStream(sOutputFilename, FileMode.Create);
                byte[] bytearrayinput = new byte[1024];
                int length;
                do
                {
                    length = cryptostreamDecr.Read(bytearrayinput, 0, 1024);
                    fsDecrypted.Write(bytearrayinput, 0, length);
                } while (length == 1024);            
                fsDecrypted.Flush();
                fsDecrypted.Close();
            }
    
            static void Main()
            {
                // Must be 64 bits, 8 bytes.
                // Distribute this key to the user who will decrypt this file.
                DESCryptoServiceProvider sSecretKey;
    
                // Get the Key for the file to Encrypt.
                sSecretKey = GenerateKey();
    
                // For additional security Pin the key.
                GCHandle gch = GCHandle.Alloc(sSecretKey.Key, GCHandleType.Pinned);
    
                // Encrypt the file.        
                EncryptFile(@"d:\MyData.txt",
                   @"d:\Encrypted.txt",
                   sSecretKey);
    
                // Decrypt the file.
                DecryptFile(@"d:\Encrypted.txt",
                   @"d:\Decrypted.txt",
                   sSecretKey);
    
                gch.Free();
            }
        }
    }

    Это работает, спасибо. А как указать свой ключ или скопировать существующий? Он же тут в строку не преобразовывается.
    2 июня 2016 г. 17:11
  • Да не за что. Обращайтесь.

    Добавьте преобразование в строку и обратно, главное убедитесь, что с этим проблем нет и до кодирования в строку и после декодирования в массиве одни и те же данные лежат.

    P.s.Если какой-то ответ или ответы помогли вам с решением проблемы, не забудьте их отметить как ответ. Для этого под сообщением есть кнопка "Пометить как ответ".

    Отвечающий
  • Да не за что. Обращайтесь.

    Добавьте преобразование в строку и обратно, главное убедитесь, что с этим проблем нет и до кодирования в строку и после декодирования в массиве одни и те же данные лежат.

    P.s.Если какой-то ответ или ответы помогли вам с решением проблемы, не забудьте их отметить как ответ. Для этого под сообщением есть кнопка "Пометить как ответ".


    А как именно сделать это преобразование, чтобы не было проблем, как в том примере?
  • Можно и как в примере, только обе части ключа надо
    • Помечено в качестве ответа Mikha_Mikhin 3 июня 2016 г. 18:29
    Отвечающий
  • Можно и как в примере, только обе части ключа надо

    Обе части ключа? o_0
  • Можно и как в примере, только обе части ключа надо

    Спасибо! Всё понял
    3 июня 2016 г. 18:29