Ответы пользователя по тегу Информационная безопасность
  • Нужна ли математика в информационной безопасности?

    Tyranron
    @Tyranron
    genby_8 смотря что Вы понимаете под "информационной безопасностью". Если это firewall настроить или внедрить подготовленные выражения SQL, то математика тут не нужна, а нужна документация к firewall/библиотеке.

    А если брать в широком смысле, то:
    • Криптография - это математика и нетривиальная: теория чисел, комбинаторика, эллиптические кривые, теория информации.
    • Криптоанализ - это математика: теория вероятности, стохастические процессы, теория игр.
    • Стеганография - тоже математика: теория кодирования и т.д.
    • Квантовая криптография - без квантовой физики и тензорного анализа туда соваться нечего.
    • Анализ/предсказание угроз - тоже математика: всякие нейронные сети, математические модели, те же стохастические процессы, и, прости господи, черт знает что ещё.

    И да, в основе всего это лежит так всеми нелюбимый матан. Без вменяемого матана, доступ во все эти замечательные разделы математики крайне ограничен и безрезультатен.
    Ответ написан
    Комментировать
  • Статья на хабре про хеширование паролей. Непонятны некоторые моменты. Поможете разобраться?

    Tyranron
    @Tyranron
    Отвечали уже не раз. Советую внимательно ознакомиться.

    Также, на том же Хабре, есть более свежие вменяемы статьи:
    Про хранение паролей в БД (обязательно читать комменты)
    Правильные ответы по криптографии: 2018 год

    Непосредственно по Вашим вопросам:

    1. При создании хэша пароля генерировать случайную соль. Сохранять в БД хэш + соль. При проверке пароля выбирать из БД хэш + соль, хэшировать полученный пароль с солью, и сопоставлять результат с хэшом из БД.

    3. Для каждого хранимого хэша пароля своя уникальная соль.

    4. Соль генерируется достаточно случайной, потому что она должна быть сложно угадываемой. Это означает, что энтропия для этого дела берется достаточно большая, и Вы можете не переживать за то, что чисто теоретически у Вас может сгенерироваться 2 одинаковые соли. Вероятность подобного случая примерно сравнимая с вероятностью того, что все молекулы воздуха в Вашей комнате возьмут и соберутся в одном углу, то есть, крайне мала(с). И даже если Вы спустите весь запас удачи своей жизни на такой воистину уникальный случай, то ничего страшного и непоправимого при этом не случится - ну поймёт злоумышленник, что конкретно у этих 2х пользователей одинаковый пароль, ну и всё на этом, - пароли то всё ещё надо взламывать.

    5. Да, можно. Хотя задача хэширования паролей и задача восстановления доступа по токену - это 2 разные задачи, с разными дано и целями, но первая задача является частью второй, ибо Вам нужно хранить в БД отпечаток секрета пользователя (коим временный токен восстановления и является). Алгоритм простой: генерируем случайный временный токен восстановления -> пишем в БД его отпечаток (хэш + соль) и время жизни -> отправляем токен пользователю -> пользователь переходит по ссылке с токеном -> проверяем валидность токена по его отпечатку и времени жизни -> заставляем пользователя ввести новый пароль. По сути, токен восстановления и являет собой одноразовый временный пароль, который предоставляет доступ для установки постоянного пароля.

    Ну и традиционный совет: используйте для получения отпечатков секретов пользователей рекомендуемые алгоритмы (Argon2, Bcrypt, scrypt, и т.п.), а не собственные реализации. Там всё сделано под капотом как надо, ибо нюансов своих в этом деле тоже хватает (стоимость по времени, стоимость по памяти, constant time сравнения, и т.д.).
    Ответ написан
    3 комментария
  • End to end шифрование сообщений, какой алгоритм/библиотеку выбрать?

    Tyranron
    @Tyranron
    Есть некий эталон в виде опенсорсного Signal: https://www.signal.org/

    У них всё в этом плане открыто и расписано.
    Дизайн доки: https://www.signal.org/docs/
    Код: https://github.com/signalapp

    Там же в дизайн доках ссылка на ихнюю готовую JS'ную либу для работы с их протоколом:
    https://github.com/signalapp/libsignal-protocol-ja...
    Ответ написан
    2 комментария
  • Минимальные настройки безопасности Linux на VPS?

    Tyranron
    @Tyranron
    Ряд моментов Вы уже сделали, но я все равно их опишу для полноты списка.

    1. Создать отдельного пользователя и хороший пароль на sudo. Не использовать больше root напрямую. Совсем.

    2. SSH. Отключаем метод аутентификации по паролю. Если Вам не нужны другие методы, то их тоже можно отключить, оставив только publickey. Отключаем возможность аутентификации root'ом. Включаем использование только 2й версии SSH протокола.

    3. Устанавливаем Fail2Ban и настраиваем чтобы после нескольких неуспешных попыток подключения по SSH банило по IP на длительное время. Кол-во попыток и время бана можно тюнить в меру своей паранойи. У меня, например, банит на час после 2х неуспешных попыток.

    4. Iptables. Действуем по принципу "запрещено все, что не разрешено". Запрещаем по умолчанию весь INPUT и FORWARD трафик снаружи. Открываем на INPUT'е 22 порт. В дальнейшем открываем порты/forwarding по мере необходимости. Если у нас предполагаются сервисы на соседних серверах нужные только для внутренней коммуникации (Memcached, Redis, и т.д.), то открываем для них порты только для определенных IP. Просто так торчать наружу для всех они не должны.

    5. Настраиваем автоматические обновления apt-пакетов. Уровень security. То есть так, чтобы обновления безопасности накатывались автоматически, но при этом не выполнялись обновления со сменой мажорной версии (дабы обезопасить себя от "само сломалось").

    6. Устанавливаем ntpd. Серверное время должно быть точным. Также временную зону сервера лучше всего установить в UTC.

    7. TLS (не SSL) используем везде где можем. Через Let's Encrypt получаем бесплатные валидные сертификаты. В конфигах веб-серверов, mail-серверов, и других приложений торчащих наружу (в том числе и OpenVPN), запрещаем/убираем использование слабых шифров. Все ключи/параметры генерируем не менее 2048 бит. Самоподписные сертификаты подписываем с помощью SHA-256 (не SHA-1). Diffie-Hellman параметры (dh.pem) под каждый сервис лучше сгенерить отдельно. Проверяем TLS сервисов через Nmap. Минимальный grade должен быть A, не должно быть warning'ов.

    8. Правильный менеджмент пользователей/групп. Приложения/сервисы не должны запускаться под root'ом (разве что они действительно этого требуют и иначе никак). Для каждого сервиса создается свой пользователь.

    9. Если предполагается upload файлов через PHP (либо другие скриптовые языки), в директории, куда эти файлы загружаются (и которая доступна снаружи), должно быть жестко отключено любое выполнение скриптов/бинарников, что на уровне ОС (x права), что на уровне веб-сервера.

    Это была база.
    Дальше, в меру своей паранойи можно за'harden'ить сервер ещё следующими моментами:
    - SELinux, chroot
    - доступ к SSH только с определенных IP (нужно иметь 3-4 VPN-сервера под рукой)

    UPD И да, все это помнить/настраивать руками каждый раз может быть запарно. Используйте Ansible и автоматизируйте процесс (там родные и YAML, Jinja2 и Python).
    Ответ написан
    10 комментариев
  • Как лучше генерировать соль рандомно или по каким нибудь данным пользователя?

    Tyranron
    @Tyranron
    Соль не является секретным параметром.
    Единственная её задача - исключить вариант использования радужных таблиц. Для этого соль должна быть сложно угадываемой.

    Потому данные пользователя - так себе соль. Лучше не морочиться и сгенерировать случайную строку вменяемой длинны. Хранить вместе с хэшом.

    Для каждого пароля - своя отдельная соль.

    Все это уже реализовано в том же алгоритме хэширования паролей Bcrypt.

    Подробный ответ на вопрос о хэшировании паролей давался уже в этом вопросе:
    Как лучше всего шифровать пароли для сохранения в БД?
    Вопрос соли там разобран тоже.
    Ответ написан
  • Как лучше всего шифровать пароли для сохранения в БД?

    Tyranron
    @Tyranron
    Чтобы лучше понять "как" и "почему", для начала следует сформулировать задачу и рассмотреть пути решения.

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

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

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

    Давайте поставим теперь себя на место злоумышленника. Располагая всем этим, как бы мы взламывали пароль?
    1. Радужные таблицы (заранее сгенерированные таблицы "хэш -> значение").
    2. Атака по словарю (сначала делается перебор по наиболее вероятным значениям).
    3. Полный перебор.
    Полный перебор хоть и решит задачу 100%, но это крайняя мера, крайне неэффективная, и, как правило, не рабочая, потому что пусть пароль и можно подобрать за десятки тысяч лет, злоумышленник столько не проживет (как и сама взламываемая система, и сам пользователь). Потому если мы обезопасились от пунктов 1 и 2 кое-как, то задачу, считай, решили.

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

    Что нужно сделать, дабы исключить вариант использования радужных таблиц?
    Сделать так, чтобы значения, подаваемые на вход хэш-функции, гарантированно в них отсутствовали. Для этого и придумали соль. В связи с этим к соли есть одно простое требование: соль должна быть сложно угадываемой.
    То есть, если у нас есть пароль "password" и соль "111", то вероятность попадания строки "password111" в радужную таблицу все ещё очень высока, а значит подобная соль плохая. А вот соль "t%Lp-,DU4=w],9c7F.N$" хороша, потому что строку "passwordt%Lp-,DU4=w],9c7F.N$" в радужную таблицу никто записывать не будет.
    Вывод: нам нужна соль для того, чтобы исключить поиск по хэшу в радужных таблицах.

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

    Далее в арсенале злоумышленника остается атака по словарю.
    Увы, полностью исключить данный вариант может только пользователь, если будет использовать стойкие и сложные к угадыванию пароли, у которых вероятность попадания в словари "крайне мала"(с).
    Но на благоразумие всех пользователей надеятся не стоит, а обезопасить их как-то надо. И здесь у нас остается возможность "вставить палку в колесо" злоумышленнику, увеличив время выполнения алгоритма. То есть просто берем и хэшируем результат повторно надцать раз, пока время выполнения алгоритма не станет достаточно длинным, например, 500ms. Нам при аутентификации пользователя (да и самому пользователю) 500ms ждать не проблема, а вот злоумышленнику делать подбор пароля со скоростью 2 пароля за секунду, уже "ой-какая-головная-боль".
    Вывод: повторяем хэширование много раз, дабы увеличить время выполнения алгоритма, что замедлит подбор паролей.

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

    Дабы реализовать все вышесказанное, к велосипеду ручонки тянуть не нужно, именно из-за вышеуказанных "заморочек" в деталях алгоритмов. Криптография дилетанства не прощает. Тем более, что уже есть де-факто промышленные стандарты.
    Например, bcrypt алгоритм (спасибо kpa6uu за упоминание). В PHP он реализован посредством стандартной password_hash() функции. В других языках тоже хватает реализаций.

    Ну и наконец-то отвечая на Ваш вопрос "как лучше всего?", то на данный момент это алгоритм Argon2, победитель последнего Password Hashing Competition. С реализациями в языках, к сожалению, пока что не так все радужно как у bcrypt.
    Ответ написан
    2 комментария