Методи зберігання паролів - все про it і програмуванні
Три підходу до зберігання паролів пояснені з прикладами.
Нині майже кожному веб-сайту треба зберігати список користувачів і паролів. Багатьом розрахованих на багато користувачів додатків потрібно метод аутентифікації користувачів, і паролі здаються нормальними.
Найпростіший підхід - просто зберігати
Найпростіший підхід до управління логінами і паролями - зберігати все у вигляді простого тексту (без шифрування і перестановки елементів) в файлі або базі даних. Результат був би таким:
Плюси зберігання паролів в незашифрованому вигляді
1. Підтвердження справжності (перевірка, що пара логіна і пароля збігається з парою в таблиці) дуже просте - порівнюються рядки!
2. Забуті паролі можна відновити - пароль є легкодоступним, якщо вказано логін.
Мінуси зберігання паролів в незашифрованому вигляді
1. По-перше, будь-який з доступом до файлу (або що може робити вибірку з таблиці) отримує негайний доступ до всіх паролів! Працівник з законним доступом до файлу може роздрукувати файл або відправити інформацію по електронній пошті, і - вуаля! - всі паролі скомпрометовані.
2. Друга проблема полягає в тому, що під час обміну аутентификационной інформацією пароль бачимо в мережі. Якщо скрізь не використовується захищена мережа, пароль буде видно при проходженні по мережі. Наприклад, навіть якщо веб-додаток використовує SSL (рівень захищених сокетів) для відправки пароля, пароль і раніше видно, коли сервер веб-додатки вибирає інформацію з віддаленої бази даних. Результати запиту передаються по мережі незашифрованими.
Чи припустимо зберігати паролі в незашифрованому вигляді?
Тоді так, зберігати паролі в незашифрованому вигляді нормально.
Шифрування паролів - трохи безпечніше
Кращий підхід до зберігання паролів (і єдина обгрунтована альтернатива, якщо користувачам треба мати можливість відновлювати паролі) - шифрування паролів перед їх збереженням.
Даний підхід заснований на володінні таємницею. Таємницею є алгоритм шифрування або ключ, який використовується разом з сучасним алгоритмом шифрування.
Шифрування паролів - оборотна операція. Таємниця використовується для спотворення пароля, і та ж сама таємниця може бути використана для відновлення оригінального пароля. Коли користувач задає пароль, збережений пароль розшифровується за допомогою таємниці, і паролі порівнюються. Альтернативний підхід - зашифрувати наданий пароль за допомогою таємниці і порівняти дві спотворені версії - збіг показує, що наданий правильний пароль.
Якщо користувачеві треба відновити пароль, збережений пароль розшифровується і доставляється користувачеві (зазвичай по електронній пошті).
Плюси шифрування за допомогою таємниці
1. Забутий або загублений пароль можна відновити.
2. Тільки одну таємницю (алгоритм або ключ) треба зберігати безпечно.
3. Для багатокористувацьких розподілених додатків при використанні шифрування треба передавати незашифрований пароль (для перевірки) або треба передавати таємницю для виконання аутентифікації в клієнті.
Мінуси шифрування паролів
1. Якщо таємниця скомпрометована, всі паролі скомпрометовані. Якщо у когось є доступ до таємниці і до сховища паролів, всі паролі можуть бути розшифровані!
2. Тільки доступу до сховища паролів досить, щоб надати інформацію про паролі, так як всі паролі шифруються за допомогою однакового алгоритму. Якщо два користувача мають однаковий зашифрований пароль, вони також повинні мати однаковий пароль. Хитрі хакери з доступом до сховища паролів можуть створити користувачів з відомими паролями і перевірити на наявність інших користувачів з таким же паролем. Такий тип атаки є різновидом атаки з відомим відкритим текстом. Такі атаки можна зупинити за допомогою солі (дивись нижче).
3. При використанні блокового шифру довжина пароля повинна зберігатися в складі зашифрованого пароля. Треба зберігати довжину, тому що блокові шифри завжди дають блок зашифрованого тексту фіксованого розміру. Якщо довжина паролі не зашифрована (наприклад, якщо зберігається як стовпець в таблиці), інформація дуже корисна для зломщиків паролів. Знання точної довжини пароля сильно спрощує вгадування пароля.
Чи прийнятно таке рішення зберігання паролів?
Якщо відновлення втраченого пароля обов'язково, то так - це єдине прийнятне рішення. Кілька рекомендацій:
Зберігання хешировать паролів - необоротне рішення
Криптографічний хеш-функція є незворотною функцією. Хеш-функція приймає вхідні дані будь-якої довжини і генерує унікальні вихідні дані постійної довжини. Наприклад, якщо пароль (будь-якої довжини) хешіруется криптографічного хеш-функцією MD5, результатом буде 128 бітове число, однозначно відповідне паролю. Криптографічні хеш-кодування працюють не тільки на паролі - якщо криптографічний хеш двох файлів ідентичний, то два файли ідентичні.
В останні роки в зв'язку з ростом обчислювальних потужностей деякі криптографічні хеш-функції більше не рекомендується використовувати (MD4, MD5, SHA1). Однак їх допустимо застосовувати для хешування паролів. Або ж змініть код так, щоб він використовував SHA2.
При зберіганні хешировать паролів пароль хешіруется (проганяється через алгоритм хешування), і отриманий хеш зберігається замість пароля. Щоб порівняти паролі, захешіруйте вказаний пароль за допомогою тієї ж самої хеш-функції і порівняйте результати. Якщо хеш-кодування збігаються, паролі збігаються.
Принадність незворотною функції полягає в тому, що неможливо обчислити пароль на основі хешу. Хешировать паролі нестійкі до атаки перебором - при наявності словника і хешу пароля хакер може обчислити хеш-кодування всіх слів в словнику, порівняти слова з хешем пароля і дізнатися пароль. Надійні паролі (містять букви, цифри і спеціальні символи) допомагають захиститися від атак перебором.
Плюси зберігання хешировать паролів
1. Оригінальний незашифрований пароль взагалі не зберігається. Навіть якщо сховище пароля скомпрометовано, тільки хеш-кодування стають загальнодоступними.
2. Довжина пароля не зберігається і не піддається оцінці, що сильно ускладнює злом пароля.
3. Не потрібна таємниця, так як ніяка таємниця не використовується для хешування пароля.
4. Для багатокористувацьких розподілених додатків хеш пароля може використовуватися для аутентифікації. При використанні шифрування доводиться передавати незашифрований пароль (для перевірки) або доводиться передавати таємницю для виконання аутентифікації в клієнті.
Мінуси зберігання хешировать паролів
1. Загублені паролі можна відновити (крім як використовувати методи перебору). Новий пароль доводиться створювати і передавати користувачу.
2. Як і для зашифрованих паролів, якщо не використовується сіль (дивись нижче), користувачі з однаковим паролем матимуть однаковий хеш пароля.
Чи прийнятно таке рішення зберігання паролів?
Так, але дотримуйтесь наступних рекомендацій:
Зберігання довжини пароля - чому і як
Чому треба зберігати довжину пароля?
Довжина пароля потрібна тільки при кодуванні і розшифровці пароля за допомогою блочного шифру. Багато блокові шифри мають розмір блоку 64 біта - розмір зашифрованих даних кратний 8 байтам. Шифрування 12 байтового пароля дасть на виході 16 байт. При розшифровці 16 байт результатом буде 16 байтовая рядок зі сміттям в останніх 4 байтах. Якщо зберігається довжина пароля, зайве доповнення можна прибрати при розшифровці пароля. Без його видалення будь-примітивні спроби порівняти рядки проваляться - 12 символьний пароль не збігається з 16 символьним розшифрованих паролем. Спроба порівняти зашифровані паролі для перевірки на збіг може провалитися, бо зайві 4 байта доповнення можуть відрізнятися від шифрування до шифрування.
Хешування не вимагає довжини пароля - хешування 12 символьного пароля за допомогою SHA2 завжди дає на виході 320 бітів, і хешування того ж самого пароля завжди дає на виході ті ж самі 320 бітів.
При використанні алгоритму шифрування, такого як ROT13 (що не рекомендується), довжина зашифрованого пароля збігається з довжиною оригінального пароля. Будь з доступом до сховища паролів тоді може отримати довжину пароля. Якщо ви вирішите використовувати алгоритм шифрування або потоковий шифр (на відміну від блокового шифру), обов'язково доповнюйте вихідні дані, щоб приховати довжину пароля.
Як можна зберігати довжину пароля?
Одне рішення - зберігати довжину пароля у вигляді стовпчика в таблиці. Недолік цього підходу полягає в тому, що якщо хакер отримає доступ до даних, то значення довжини пароля дуже полегшує атаку перебором. Знання, що пароль містить всього 5 символів, дозволяє хакеру обмежити число спроб підбору пароля, необхідних для злому пароля.
Рішення краще - зберігати довжину пароля в складі зашифрованою рядки. Довжину пароля можна додати до початку рядка пароля (наприклад, як перші два символи). При розшифровці пароля за першими двома символами відновлюється довжина, і пароль безпечно обрізається. Зберігання довжини, зашифрованою разом з паролем, гарантує, що ніхто не може мати доступ до довжини пароля без знання таємниці, використовуваної для шифрування пароля.
Приклад - Зберігання довжини і обрізання паролів
Зберігання повідомлення разом з довжиною:
Відновлення повідомлення з двійкового масиву:
Соління - сіль покращує смак всього
Хешування (або шифрування) одного і того ж пароля для двох користувачів дає один і той же результат. Періодична інформація може використовуватися зловмисно для отримання паролів. Користувач з доступом до сховища паролів може встановити свій пароль у словникову слово, а потім просканувати сховище паролів на наявність іншого користувача з таким же хешировать або зашифрованим паролем. При виявленні збігу пароль того користувача буде зламаний.
Просте соління - використання додаткового шматка даних
Щоб уникнути вищезгаданої проблеми можна ввести деяку варіацію в хешування (або в алгоритм шифрування). Наприклад: якщо приєднати логін на початку пароля, хешировать або зашифрований результат більше не буде збігатися.
Зрозуміло, Боб і Ів мають однаковий пароль. Ще гірше, якщо хакер отримає сховище паролів, хакер зможе заздалегідь обчислити хеш-кодування для всього словника і шукати збіги в сховище паролів, сильно прискоривши процес злому.
Якщо додати логін в поєднання:
Зараз Боб і Ів мають різні хеші паролів. Якщо хакер заволодіє сховищем паролів, тепер хакеру доведеться обчислити хеш кожного пароля конкретно для кожного користувача. Хакеру доведеться заздалегідь обчислити словникові хеші з префіксом "Bob." Для Боба і з префіксом "Eve." Для Верб - нелегке завдання.
Просунуте соління - використання випадкової інформації
Використання випадкової солі значно підвищує якість шифрування паролів і сильно ускладнює злом перебором.
Щоб використовувати випадкову сіль, обчисліть випадкове число і використовуйте випадкове число як компонент при обчисленні хешу або при шифруванні. Зберігайте випадкове число в стовпці бази даних, щоб число було доступно пізніше при перевірці пароля.
При первинному збереженні пароля для Боба:
1. Обчислити випадкове число (використовувати надійний криптографічний випадковий генератор, такий як в System.Security.Cryptography).
2. Додати випадкове число до рядка пароля.
3. Обчислити хеш або зашифрувати отриманий рядок.
4. Зберегти хеш або результат шифрування і випадкове число в сховище паролів.
При порівнянні паролів слідувати таким же алгоритмом:
1. Дістати випадкове число зі сховища паролів.
2. Додати випадкове число до рядка пароля.
3. Обчислити хеш або зашифрувати отриманий рядок.
4. Порівняти результат зі збереженим хешем або зашифрованим паролем, збіг означає збіг паролів.
Використання випадкового числа краще, ніж використання логіна. Логіни не надто випадкові - вони дотримуються дуже строгих правил. Випадкові числа (що виходять з надійного криптографічного генератора випадкових чисел) вносять більше випадковості в отриманий хеш або зашифровані вихідні дані. Зауважте, що якщо в якості солі використовується логін, то логін взагалі не можна міняти. При зміні логіна хеш стане недійсним.
Кодування двійкових вихідних даних у вигляді тексту
Вихідні дані з хеш-функцій і алгоритмів шифрування виконавчі. Щоб зберігати двійкові дані у вигляді текстових рядків, можна закодувати дані.
Дві популярні схеми кодування - UUENCODE (популярна в світі Unix) і Base64 (популярна скрізь). Base64 - схема кодування, що застосовується для перетворення двійкових вкладень для відправки через електронну пошту SMTP (простий протокол пересилання пошти).
Приклад - кодування двійкового масиву в рядок
Приклад - розкодування рядки в двійковий масив
Алгоритми шифрування і приклади
Каркас .NET (System.Security.Cryptography) включає в себе вбудовану підтримку декількох алгоритмів шифрування:
• DES - старий, що вийшов з ужитку.
• TripleDES - старий, але все ще стійкий.
• RC2 - старий, але все ще корисний.
• Rijndael (AES) - сучасний.
Приклад - кодування рядка:
Приклад - розкодування рядки:
Алгоритми хешування і приклади
Каркас .NET (System.Security.Cryptography) включає в себе вбудовану підтримку декількох криптографічних хеш-функцій:
Приклад - хешування рядка:
Приклад - порівняння двох хешів на рівність:
висновок
У вас вже є достатньо інформації, щоб приймати обґрунтовані рішення щодо зберігання паролів.
• Якщо треба відновлювати паролі, використовуйте шифрування.
• Якщо не треба відновлювати паролі, використовуйте хеші (більш безпечно).
• Що б ви не робили, соліть паролі.
• Завантажити демонстраційний проект - 5.26 КБ • Завантажити оригінали - 12.2 КБ Введення Варто відзначити, що представлений метод можна розширити до вміщення опціонів з декількома постійними бар'єрами. Після вивчення простого прикладу перейдемо до більш складним опціонах до мінливих в часі.
• Завантажити оригінали - 251 Кб • Завантажити демонстраційний проект - 181 Кб Введення Історія нейронних мереж починається в 1950-х рр. коли була представлена архітектура найпростіших нейронних мереж. Після початкової роботи в області ідея нейронних мереж стала дуже популярною. Але потім область.