2010-07-11 2 views
4

играл с шифрованием и дешифрования файлов в VC# Express 2010C# Шифрование файлов и дешифрование вопрос

Все учебники и документация, которые я видел требует двух FileSteams для того, чтобы зашифровать файл. Один для чтения незашифрованной версии, а другой для шифрования. Когда я на самом деле написал код, он все время выдавал ошибку, сообщая мне, что он не может открыть файл, потому что он был открыт другим процессом в выходном потоке.

Я предполагаю, что это потому, что файл открыт входным сигнальным потоком. Значит, я должен указать другое имя файла? Таким образом, даже после успешной операции я узнаю, что исходный незашифрованный файл в каталоге и отдельная зашифрованная версия? Разве это не побеждает точку? Или я делаю что-то не так? Мой код похож на этот ...

public string filename = "test.xml"; 
using(FileStream input = new FileStream(filename, FileMode.Open, FileAccess.Read)) 
using(FileStream output = new FileStram(filename, FileMode.Open, FileAccess.Write)) 
using(....all the crypto stream and transform stuf...) 
{ 
    ...do the encryption.... 
} 

ответ

0

Использование File.ReadAllBytes. Затем эти байты отправляются на ваш шифр, должны работать.

3

Вы правы, но это не побеждает точку. Криптографические API-интерфейсы (потоковые) предназначены для шифрования от Src до Dst. Думайте шифровать вывод при отправке/приеме по сети и т. Д. Это упрощает их, как и должно быть.

Вы затрудняете проблему, используя тот же файл для Src и Dst. Это не совсем невозможно, но, как и копирование файла, он нуждается в дополнительной осторожности.

Учтите, что шифрование в общем случае увеличит размер файла. Поэтому не шифровать файл на месте. Расшифровка может быть, но я бы не рискнул.

Что вам нужно - это файл Temp и действие переименования после завершения.

+0

Это касается другой проблемы: ваш файл небезопасен, если злоумышленник имеет доступ к вашему компьютеру.Если вы хотите зашифровать файл, вы должны убедиться, что незашифрованные байты никогда не касаются жесткого диска. Если вы откроете свой сверхсекретный бизнес-план словом, всевозможные временные файлы собираются записать на диск, который вы никогда не сможете очистить. Если вы хотите защитить файл, вам действительно нужно шифрование всего диска. – TwentyMiles

1

В вашем примере вы не можете создать отдельный поток для ввода и вывода в одном файле, но вы можете создать дескриптор, который будет читать и писать. В перечислении FileAccess есть атрибут flags, поэтому вы просто скажете var handle = new FileStream(filename, FileAccess.Read | FileAccess.Write);. Очевидным недостатком этого является то, что вы потеряете данные, если ваше шифрование не завершится успешно.

Я рекомендую иметь отдельный файл для вывода, хотя, по крайней мере, вы не потеряете данные, если ваша программа неожиданно прерывается. Если шифрование завершено успешно, удалите оригинал и переименуйте зашифрованный файл с исходным именем файла.

+0

Это как другие приложения для шифрования файлов? Я никогда не видел остаточной копии незашифрованного источника после операций шифрования. Я должен выводить во временный файл .... создать оператор if для мониторинга успеха операции, а затем, если он будет успешным, THEN удалите оригинал и переименуйте временное, чтобы его заменить? Это гарантирует, что данные не будут потеряны? – Stev0

+0

Так большинство приложений работало в течение дня. Теперь я не уверен. Временные файлы обычно устанавливаются скрытыми и могут находиться во временной папке на диске. Эта же идея используется в шифровании файловой системы - если вы перемещаете файл в зашифрованную файловую систему, оригинал не будет удален до тех пор, пока ход не будет успешно завершен. Вы должны как-то сохранить исходные данные, пока не узнаете, что шифрование завершено успешно, потому что это может быть что-то простое, как нехватка памяти, или полный диск, из-за которого ваше приложение терпит неудачу. –

+0

Если вам действительно нужно переработать существующий файл, я бы предложил его прочитать в фиксированных размерах блоков (скажем, что-то вроде 4096kb - что-то, что легко впишется в память). Если и только если каждый блок успешно завершен, перезапишите исходный блок, но если нет, выведите в файл журнала положение, в котором файл зашифрован, и любые потенциальные данные, чтобы помочь восстановить его. (т. е. векторы инициализации, ключи, причина ошибки). –

0

Существует еще один параметр, в котором можно указать, следует ли разрешить другой процесс чтения или записи в файл

OpenFile это имя файла, тип строки.

using (FileStream fileIn = new FileStream(openFile, FileMode.Open, FileAccess.Read, FileShare.Write)) 
using (FileStream fileOut = new FileStream(openFile, FileMode.Open, FileAccess.Write, FileShare.Open)) 

Таким образом, вы можете читать и писать в тот же файл.

while (myfileStream.Position < fileLength) 
{ 

    fileIn .Read(buffer, 0, 51200); 

    buffer = encrypt(buffer); 

    fileOut .Write(buffer, 0, 51200);     


} 

Хотя это легко, и вы не должны писать во временный файл или придется переместить/переименовать и т.д., это может быть очень опасно, где, если перерывы шифрования вдруг по какой-то причине, вы потеряете данные ! A

Кроме того, функция шифрования - это то, что я реализовал. AesCryptoServiceProvider вместе с CryptoStream можно использовать :)

+1

Я думаю, что ваше состояние не работает. Но хуже, положение fileOut начнет обгонять файл fileIn, и ваш файл будет искажен без ремонта. –

+0

@ Хенк: Да. Ты прав. Но проблема была в мобильных устройствах, если кто-то хочет зашифровать 500 МБ-файл, создание еще 500 МБ-файла было бы невозможно из-за ограничений ресурсов. Я признаю, что это опасно и возможно ошибочно, но что-то в этом роде должно быть сделано для устройств с ограниченными ресурсами, не так ли? Есть ли другой подход? :) –

+1

В OQ не упоминается Mobile, поэтому вы можете расширить эту проблему. Возможно, вы сможете решить ситуацию без tempfile, добавив сжатие в микс. Но это не гарантировано (он сломается, если файл Src недостаточно сжимается, т.е. уже сжат). –

Смежные вопросы