Написать эту заметку мне помогла статья о хешировании паролей: https://crackstation.net/hashing-security.htm и книга Dovecot: POP3/IMAP servers for enterprises and ISPs (root's reading), которую написал автор dovecot Peer Heinlein.
Для авторизации пользователей почтовому серверу (или любому другому веб-сервису) требуется иметь базу с именами пользователей и их паролями.
При таких условиях возникает две угрозы: 1. Компрометация сервера: злоумышленник получает доступ к базе данных и может узнать все пароли 2. Передача информации в процессе аутентификации пользователей через незащищенные сети: злоумышлинник может получить один или множество паролей "прослушивая" трафик.
Для борьбы с угрозой 1. существует метод хранения паролей виде хеша, т.е. набора символов фиксированной длины, который получается в процессе обработки данных (в нашем случае пароля, придуманного пользователем) с приминением криптогафической функции. Функции, применяемые для хеширования паролей, такие как, например, SHA256 и SHA512 работают таким образом что вычисление хеша заданной строки происходи быстро (за милисекунды) а на то, чтобы обратить действие функции (узнать пароль по хешу) требуются годы.
Однако для того, чтобы узнать пароль, имея только хеш, не обязательно пытаться обратить математеческую функцию. Можно сгенерировать значения хеш функции для определенного набора слов (или для любого набора символов фиксированной длины) и сравнивая значения с имеющимся хешем узнать исходный пароль.
Для того, чтобы защитить базу паролей от такого рода атак, применяется т.н. соль (salt), то есть набор случайных символов, который добавляется к паролю при хешировании. Таким образом для каждого пароля (даже если среди них встречаются одинаковые) результат работы хеш-функции будет разным, что делает вышеописанный метод неэффективным. Соль не должна быть секретом, она может храниться в базе в явном виде вместе с паролями, т.к. требуется для проверки хеша.
При таком сценарии процесс аутентификации выглядит следующим образом: пользователь предоставляет пароль в текстовом виде, сервер вычисляет хеш предоставленного пароля и сравнивает его с хешем хранящимся в базе. Если хеши совпадают, пользователь получает доступ.
Даже если злоумышлинник получит доступ к базе паролей, он не сможет аутентифицироваться, т.к. благодаря хешированию с солью не сможет получить исходный пароль.
Для борьбы с угрозой 2. существует т.н. CRAM (challenge-response authentication method), в рамках которого в процессе аутентификации пароль в явном виде не передается, а передается только хеш. Но в данном случае появляется сложность: для того, чтобы работали безопасные методы аутентификации (т.е. не передающие пароль в явном виде) требуется хранить пароль в явном виде на сервере. Таким образом, если злоумышленник получает доступ к базе, он получает доступ ко всем паролям. Некоторые системы предлагают использовать CRAP и хранить пароли в виде хешей, но компрометация базы в таком случае так же опасна, как если бы пароли хранились в явном виде, т.к. используя хеш, злоумышленник может аутентифицироваться на сервере, даже не зная пароля, поскольку CRAM оперериует именно хешами.
Таким образом, существует 2 безопасных ( с точки зрения защиты от описанных выше угорз) метода хранения паролей и аутентификации:
1. Использование метода аутентификации SCRAM, которая аналогична CRAM, но работает с "солеными" хешами. Благодаря этому, получение злоумышленником доступа к базе паролей на сервере или прослушивание трафика не позволят ему аутентифицироваться на сервере.
2. Использование метода аутентификации PLAIN/LOGIN при котором пароли передаются в явном виде, хранение паролей в виде "соленых" хешей. Чтобы защититься от прослушивания трафика, следует использовать SSL/TLS
Для авторизации пользователей почтовому серверу (или любому другому веб-сервису) требуется иметь базу с именами пользователей и их паролями.
При таких условиях возникает две угрозы: 1. Компрометация сервера: злоумышленник получает доступ к базе данных и может узнать все пароли 2. Передача информации в процессе аутентификации пользователей через незащищенные сети: злоумышлинник может получить один или множество паролей "прослушивая" трафик.
Для борьбы с угрозой 1. существует метод хранения паролей виде хеша, т.е. набора символов фиксированной длины, который получается в процессе обработки данных (в нашем случае пароля, придуманного пользователем) с приминением криптогафической функции. Функции, применяемые для хеширования паролей, такие как, например, SHA256 и SHA512 работают таким образом что вычисление хеша заданной строки происходи быстро (за милисекунды) а на то, чтобы обратить действие функции (узнать пароль по хешу) требуются годы.
Однако для того, чтобы узнать пароль, имея только хеш, не обязательно пытаться обратить математеческую функцию. Можно сгенерировать значения хеш функции для определенного набора слов (или для любого набора символов фиксированной длины) и сравнивая значения с имеющимся хешем узнать исходный пароль.
Для того, чтобы защитить базу паролей от такого рода атак, применяется т.н. соль (salt), то есть набор случайных символов, который добавляется к паролю при хешировании. Таким образом для каждого пароля (даже если среди них встречаются одинаковые) результат работы хеш-функции будет разным, что делает вышеописанный метод неэффективным. Соль не должна быть секретом, она может храниться в базе в явном виде вместе с паролями, т.к. требуется для проверки хеша.
При таком сценарии процесс аутентификации выглядит следующим образом: пользователь предоставляет пароль в текстовом виде, сервер вычисляет хеш предоставленного пароля и сравнивает его с хешем хранящимся в базе. Если хеши совпадают, пользователь получает доступ.
Даже если злоумышлинник получит доступ к базе паролей, он не сможет аутентифицироваться, т.к. благодаря хешированию с солью не сможет получить исходный пароль.
Для борьбы с угрозой 2. существует т.н. CRAM (challenge-response authentication method), в рамках которого в процессе аутентификации пароль в явном виде не передается, а передается только хеш. Но в данном случае появляется сложность: для того, чтобы работали безопасные методы аутентификации (т.е. не передающие пароль в явном виде) требуется хранить пароль в явном виде на сервере. Таким образом, если злоумышленник получает доступ к базе, он получает доступ ко всем паролям. Некоторые системы предлагают использовать CRAP и хранить пароли в виде хешей, но компрометация базы в таком случае так же опасна, как если бы пароли хранились в явном виде, т.к. используя хеш, злоумышленник может аутентифицироваться на сервере, даже не зная пароля, поскольку CRAM оперериует именно хешами.
Таким образом, существует 2 безопасных ( с точки зрения защиты от описанных выше угорз) метода хранения паролей и аутентификации:
1. Использование метода аутентификации SCRAM, которая аналогична CRAM, но работает с "солеными" хешами. Благодаря этому, получение злоумышленником доступа к базе паролей на сервере или прослушивание трафика не позволят ему аутентифицироваться на сервере.
2. Использование метода аутентификации PLAIN/LOGIN при котором пароли передаются в явном виде, хранение паролей в виде "соленых" хешей. Чтобы защититься от прослушивания трафика, следует использовать SSL/TLS