Как я могу защитить зашифрованные файлы от повреждения перед расшифровкой
Я шифрую PDF-файл, используя Rijndael
алгоритм. Шифрование и дешифрование работает отлично. Шифрование преобразует файл PDF в файл с .key
расширение.
Проблема в том, что я могу открыть этот файл в notepad
(он показывает некоторые символы Unicode) и испортит его. Рассмотрим сценарий, который:
Я открыл файл и удалил несколько символов / добавил несколько символов и save the notepad file
, Если я передал этот файл в метод расшифровки, я получу поврежденный файл в качестве вывода. Я знаю, что это происходит потому, что при добавлении или удалении символов в файле byteStream изменяется (изменяется заполнение).
Вот мой вопрос:
Есть ли способ преодолеть эту проблему? Другими словами, отключить редактирование зашифрованного файла?**
Ниже приводится метод, который я использую для шифрования,
Код VB
Dim plainFile As String = basePath & "\cryptoText.pdf"
Dim password As String = "somePass"
Dim UE As New UnicodeEncoding()
Dim key As Byte() = UE.GetBytes(password)
Dim cryptFile As String = basePath & "\cryptoText.key"
Dim fsCrypt As New FileStream(cryptFile, FileMode.Create)
Dim RMCrypto As New RijndaelManaged()
Using csKey As New CryptoStream(fsCrypt, RMCrypto.CreateEncryptor(key, key), CryptoStreamMode.Write)
Dim FsIn As New FileStream(plainFile, FileMode.Open)
Dim data As Integer
While (data = FsIn.ReadByte()) <> -1
csKey.WriteByte(CByte(data))
End While
FsIn.Close()
End Using
fsCrypt.Close()
Код C#
string plainFile = basePath + "\\cryptoText.pdf";
string password = "somePass";
UnicodeEncoding UE = new UnicodeEncoding();
byte[] key = UE.GetBytes(password);
string cryptFile = basePath + "\\cryptoText.key";
FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create);
RijndaelManaged RMCrypto = new RijndaelManaged();
using (CryptoStream csKey = new CryptoStream(fsCrypt, RMCrypto.CreateEncryptor(key, key), CryptoStreamMode.Write)) {
FileStream FsIn = new FileStream(plainFile, FileMode.Open);
int data = 0;
while ((data == FsIn.ReadByte()) != -1) {
csKey.WriteByte(Convert.ToByte(data));
}
FsIn.Close();
}
fsCrypt.Close();
примечание: я пробовал это и в C#, и в vb.net, так что помечаю свой вопрос обоим.
2 ответа
Ответ сделать две вещи,
- Шифрование,
- Добавьте к нему HMAC (например, SHA256, использующий тот же ключ) в зашифрованных данных и прикрепите его к концу криптопотока.
https://msdn.microsoft.com/en-us/library/system.security.cryptography.hmacsha256%28v=vs.110%29.aspx
Затем, когда вы расшифровываете, вы
- Убедитесь, что HMAC действителен,
- IFF# 1 проверяет, затем и только потом расшифровывает
Кроме того, если это не локальные файлы, а какой-то сетевой поток, то вы должны выполнять проверку в постоянное время - вы не можете использовать обычные функции сравнения байтов. Это из-за времени атаки. Но для локальных файлов вы можете делать любые сравнения, которые вам нравятся, поскольку нет временных атак.
Вы не можете помешать кому-либо открыть файл в любом редакторе и изменить его. Пометка файла как доступного только для чтения может немного помочь, но не решит проблему.
Вместо этого вам следует сгенерировать хеш зашифрованного файла, а затем, прежде чем расшифровать его, проверить, что файл все еще генерирует тот же хеш. Если это не так, вы знаете, что файл был подделан.