безопасна ли эта функция шифрования на основе xor? - PullRequest
3 голосов
/ 24 декабря 2010

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

Все, что я прошу, это если я допустил какие-либо ошибки, которые могли бы показать скрытый текст опытному человеку, не применяя грубую силу к строке. (Я знаю, что в php есть модуль только для шифрования, но это плохая версия на случай, если модуль шифрования недоступен.) Второе: Я не прошу вас переписать эти функции или написать что-то для меня , я прошу лишь простое руководство о том, что я сделал неправильно. Я знаю, что одним из возможных нарушений безопасности является то, что я по умолчанию использую сальсу, которая представляет собой все нули для пустой строки, но преимущество в том, что это самый длинный хеш, доступный в php, и, во-вторых, какой дурак будет использовать пустой пароль для защиты своих данных?

function crapt($str,$pass,$hmac = false,$meth = 'salsa20') {
   $hash = pack('H*',($hmac===false) ? hash($meth,$pass) : hash_hmac($meth,$pass,$hmac));
   $str = gzdeflate($str,9);
   $tmphash = pack('H*',sha1(sin(microtime(1))));
   $str = $tmphash.((string)$str ^ (string)str_repeat($tmphash,strlen($str)/strlen($tmphash)+1));
   $str .= pack('H*',sha1($str));
   return (string)$str ^ (string)str_repeat($hash,strlen($str)/strlen($hash)+1);
}

function decrapt($str,$pass,$hmac = false,$meth = 'salsa20') {
  $hash = pack('H*',($hmac===false) ? hash($meth,$pass) : hash_hmac($meth,$pass,$hmac));
  $str = (string)$str ^ (string)str_repeat($hash,strlen($str)/strlen($hash)+1);
  $check = substr($str,-20);
  $str = substr($str,0,strlen($str)-20);
  if(pack('H*',sha1($str))!==$check) return false;
  $tmphash = substr($str,0,20);
  $str = substr($str,20);
  return gzinflate((string)$str ^ (string)str_repeat($tmphash,strlen($str)/strlen($tmphash)+1));
}

var_dump(decrapt(crapt('sometext','secretpassword'),'secretpassword'));

Ответы [ 3 ]

13 голосов
/ 24 декабря 2010

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

7 голосов
/ 24 декабря 2010

Ваши алгоритмы работают в блоках длины strlen($hash)==strlen($tmphash). EDIT : неверно, но см. Ниже.

В зашифрованном тексте первый из таких блоков равен ($tmphash XOR $hash).Следующие из них равны (a_block_of_plaintext XOR $tmphash XOR $hash).

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

Я не программист PHP, поэтому, возможно, я что-то упускаю, но практическая атака не сильно отличается от этого.

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

РЕДАКТИРОВАТЬ : перечитывая вопрос, я заметил, что $hash и $tmphash имеют разную длину.$hash - 512 бит, а $tmphash - 160 бит.Однако это не меняет основную идею;поскольку наименьшее общее кратное 512 и 160 равно 2560, блоки синхронизируются каждые 2560 бит.Поэтому вы можете расшифровать только первые 160 бит каждого 2560-битного блока.

3 голосов
/ 24 декабря 2010

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

Я вижу строку:

 $tmphash = pack('H*',sha1(sin(microtime(1))));

и я думаю, что это твой ключ. Как я уже сказал, мой PHP довольно плох, поэтому, пожалуйста, поправьте меня, если я ошибаюсь.

Если функция php sha1 возвращает 40-битное шестнадцатеричное число, это дает вам пространство ключа WEP. В последний раз, когда я проверял, WEP можно взломать примерно за 3 минуты. Я не совсем уверен, основано ли это на врожденных уязвимостях в протоколе из-за утечки информации, или это из-за очень маленького пространства ключей. Однако 16 ^ 40 не кажется достаточно большим пространством для ключей для криптографической защиты.

Кроме того, исходя из этого, все, что мне нужно знать, это приблизительное время, когда пользователь сгенерировал этот запрос, и вы значительно сократили бы пространство для ключей, которое необходимо искать. Если метод microtime () в php фактически даст вам текущие микросекунды с начала эпохи, это уменьшит мое пространство поиска ключей с 16 ^ 40 (вывод php ofs1?) До количества микросекунд в таймфрейме, в котором я уверен, что ваш пользователь получил эти данные от вас. Я мог бы написать взломщик, который будет проходить через это пространство клавиш с того момента, когда я чувствую себя наиболее уверенно (время, когда я нюхал пакет), и отступать оттуда, пока не достигну своего рода порога.

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

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

-Брайан Дж. Стинар-

...