простое шифрование текстового файла на основе ключа - PullRequest
7 голосов
/ 28 февраля 2012

Я пытаюсь реализовать простую технику шифрования текстовых файлов, и я использую следующий код для этого.Код не написан мной, я просто погуглил и получил его.Техника шифрования кажется довольно простой, лаконичной и простой в реализации.Я вижу, что у него есть только одна функция, которая может выполнять шифрование и дешифрование на лету.Просто передайте ключ, он сделает свое дело.Тем не менее, я просто хотел знать, могу ли я проверить, передан ли ключ пользователем правильно или нет.В настоящее время он будет просто шифровать / дешифровать текстовый файл на основе переданного ключа.Но нет никакого механизма, чтобы проверить, расшифровываем ли мы с правильным ключом или нет.Какой бы ключ мы ни передавали, он будет расшифрован, но не будет читаемым.Любая идея, как решить эту проблему ..?

procedure TEnDeCrypt.EnDecryptFile(pathin, pathout: string; Chave: Word);
var
  InMS, OutMS: TMemoryStream;
  cnt: Integer;
  C: byte;
begin
  InMS  := TMemoryStream.Create;
  OutMS := TMemoryStream.Create;
  try
    InMS.LoadFromFile(pathin);
    InMS.Position := 0;
    for cnt := 0 to InMS.Size - 1 DO
      begin
        InMS.Read(C, 1);
        C := (C xor not (ord(chave shr cnt)));
        OutMS.Write(C, 1);
      end;
    OutMS.SaveToFile(pathout);
  finally
    InMS.Free;
    OutMS.Free;
  end;
end;

Ответы [ 3 ]

7 голосов
/ 28 февраля 2012

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

Вы можете проверить ключ, хешируя расшифрованный текст, и убедитесь, что контрольная сумма совпадает.

Если вы используете сильный алгоритм хеширования, такой как SHA256, для генерации контрольной суммы, пользователю будет сложно автоматизировать атаку методом перебора, потому что это будет в вычислительном отношении дорогостоящим.

Чтобы гарантировать, что файлВы можете также сохранить контрольную сумму в зашифрованном файле и сохранить ее в заголовке файла.В противном случае невозможно будет отличить неверный пароль от усеченного файла.

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

7 голосов
/ 28 февраля 2012

Если вам известно о типе содержимого вашего файла (будь то двоичный файл / текстовый файл и т. Д.), То вы можете взять образец текста и посмотреть, есть ли какие-либо не-ASCII или символы, которые не ожидаются в файле после расшифровки.

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

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

2 голосов
/ 29 февраля 2012

Правильный способ сделать то, что вы просите, - это зашифровать-затем-аутентифицировать данные. Здесь есть некоторое уместное обсуждение: Должны ли мы MAC-затем-шифровать или encrypt-then-MAC?

Обычным способом является сначала использование стандартного шифра в стандартном режиме, например AES в режиме CBC, а затем вычисление HMAC (например, HMAC-SHA256) по тексту шифра. Есть также некоторые режимы шифрования, такие как CCM, EAX, GCM, которые будут выполнять как шифрование, так и аутентификацию.

Не используйте для этого хеш вместо HMAC.

Ключ, который вы используете для шифрования, должен быть независимым от ключа, который вы используете для аутентификации. Вы могли бы, например, генерировать оба случайно, но абсолютно не , используя функцию System.Random. Если вы развертываете в Vista SP2 или более поздней версии, вы можете использовать CryptGenRandom из Windows API, но в противном случае вам следует использовать криптографическую библиотеку с поддержкой генерации криптографических случайных чисел.

Если вы используете шифрование на основе пароля, используйте реализацию PBKDF2 для получения ключа шифрования и ключа аутентификации. Существует четыре распространенных способа обеспечить независимость двух ключей:

  • Используйте два отдельных значения Соли;
  • Используйте одну соль, но объедините ее с отдельными "ярлыками", например, строки 'E' и 'A' соответственно
  • Сгенерируйте вдвое более длинный производный ключ и используйте одну половину как ключ шифрования, а другую половину как ключ аутентификации, или
  • Пусть полученный ключ является «ключом шифрования ключа», который вы используете для шифрования случайно сгенерированных ключей шифрования и ключей аутентификации.
...