Пароли должны храниться в зашифрованном виде. Создаем триггер который шифрует пароль перед добавлением записи:
Код:
DELIMITER $$ CREATE TRIGGER users_bi BEFORE INSERT ON users FOR EACH ROW BEGIN SET NEW.password = SHA(NEW.password); END; $$ DELIMITER ;
Теперь можно делать добавить запись (зная что пароль автоматически зашифруется):
Код:
INSERT INTO users VALUES ('alex', 'secret_password');
Приемущества этого метода: • мы на 100% уверены что пароль будет зашифрован
• алгоритм шифрования находится только в одном месте: в триггере
Неудобства этого метода: Допустим мы создаем резервную копию таблицы (в SQL файл) с помощью утилиты mysqldump.
Когда мы восстановливаем данные (с SQL файла):
• происходит выполнение INSERT команды
• триггер выполняется и закодированный пароль шифруется еще раз, что приводит к порче данных
Решение проблемы: Так как в MySQL нельзя временно приостановить действия триггеров, их можно временно удалить DROP TRIGGER командой.
Но хорошо если при восстановлении триггеры работают проверяя целостность данных.
Плохо если при этом триггеры изменяют или добавляют данные. Что является рутинной работой триггеров (даже не связанных с шифрованием).
Вопросы: 1. Это нормально при восстановлении временно удалять триггера из базы?
2. Если удаляем триггера, то восстанавливать работающую ("в прямом эфире") базу нельзя. Ее надо временно закрыть.
3. Писать алгоритм шифрования в триггере это тоже нормально?
_________________ Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
Последний раз редактировалось AlexShop 19 Июль 2008, 19:15:41, всего редактировалось 1 раз.
Неверно. Он будет в двух местах. Догадайся, где еще.
Ага, если даже и не в трех местах:
1. INSERT - добавляем запись о новом пользователе
2. SELECT - при авторизации, проверяем есть ли пользователь с данным паролем
3. UPDATE - меняем пароль, если пользователь забыл его
Значит хеширование пароля может быть вынесено в отдельную MySQL функцию, например: encrypt_password(). Теперь что бы шифровать пароль, эту функцию можно вызывать в трех местах:
1. В триггере, пример который я привел в самом начале.
2. В специальной MySQL процедуре, которая шифрует пароль и добавляет пользователей в базу
3. В приложении (например PHP)
Приведу примеры добавления пользователей для каждого случая.
1. Если триггер автоматически шифрует, значит делаем простой INSERT:
Код:
INSERT INTO users VALUES ('alex', 'secret_password')
2. Хранимая MySQL процедура тоже шифрует пароль. Вызов этой процедуры мог бы выглядеть так:
Код:
CALL insert_user('alex', 'secret_password')
3. PHP приложение составляет SQL запрос. Запрос использует нашу MySQL функцию encrypt_password() что бы шифровать пароль:
Код:
$query = "INSERT INTO users VALUES ('alex', encrypt_password('secret_password') )";
Я пока склоняюсь к второму случаю (хранимая MySQL процедура).
Но почему не триггеры? Ведь при восстановлении с резервной копии, в любом случае триггеры нало временно отключать (удалять).
_________________ Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
"Решение несуществующих проблем" является одним из определений понятия "интеллектуальная мастурбация".
Здравый смысл говорит, что нужно сокращать количество передач паролей в живом виде по нешифрованным каналам. Даже если это канал между PHP и MySQL. В нашем случае, внося изменение, не решающее ни какой проблемы, мы снижаем безопасность приложения. См. предыдущий абзац.
Здравый смысл говорит, что нужно сокращать количество передач паролей в живом виде по нешифрованным каналам.
В таком случае PHP должно шифровать пароль и вставлять его в зашифрованном виде в MySQL запрос.
Такое не всегда подходит, потому что я хочу добавлять пользователей в базу без PHP.
Ладно пока оставлю шифрование в триггере (который вызывает функцию), посмотрю как это на практике получается.
Еще вопрос. К примеру:
- есть данные в таблице которые надо расшифровать.
- расшифровывать данные можно с помощью MySQL процедуры (или сделать VIEW с привилегиями?)
- но если злоумышленник получит доступ к базе, он сможет прочитать данные, потому что механизм дешифрования лежит в самой базе!
Получается что алгоритм дешифрования надо хранить как можно дальше от базы данных, например в PHP?
Значит (что бы сохранить симметрию приложения) шифрование тоже должно находиться в PHP.
Мне просто интересно как защита данных делается в нормальных организациях?
_________________ Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
Такое не всегда подходит, потому что я хочу добавлять пользователей в базу без PHP.
Что значит "не всегда происходит"? Ты написал код в PHP, а он, шайтан, взял и не исполнился? Это -- к доктору Кашпировскому, пусть наложит заговор на PHP.
Цитата:
Мне просто интересно как защита данных делается в нормальных организациях?
Начнем с простого: ты осознаешь, что такое шифрование и чем оно отличается от того, что ты писал выше в своем коде?
Что значит "не всегда происходит"? Ты написал код в PHP, а он, шайтан, взял и не исполнился? Это -- к доктору Кашпировскому, пусть наложит заговор на PHP.
Ну мне спокойнее спится, когда я знаю что все операции с базой данных я могу делать в окошке терминала. Может это только мои проблемы со сном, и мне надо идти к доктору?
Crazy писал(а):
Начнем с простого: ты осознаешь, что такое шифрование и чем оно отличается от того, что ты писал выше в своем коде?
Да, я отличаю:
односторонее шифрование, когда нельзя расшифровать данные (хеширование, в первом примере)
от
двухстороннего шифрования, когда я хочу иметь возможность расшифровать данные
_________________ Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
Ответ: защита от несанкционированного доступа к MySQL реализуется штатными средствами операционной системы.
Это защита от доступа.
А как лучше реализовать защиту данных, на тот случай если злоумышленник уже получил доступ?
Итак расставим все по порядку:
1. Я хочу проделывать любые операции с базой (читать зашифрованные данные) в окошке терминала (на тот случай если Apache полетит).
2. Механизм дешифрования лежит в самой базе (в виде хранимой процедуры или функции).
3. Злоумышленник получив доступ к базе, сможет использовать механизм дешифрования и читать данные.
Если механизм дешифрования лежит в PHP, пункты 1 и 3 невыполнимы. Но я хочу выполнять пункт 1.
Вот такая диллема и как ее решить?
_________________ Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
Последний раз редактировалось AlexShop 19 Июль 2008, 20:14:29, всего редактировалось 1 раз.
Шифрование имеет смысл если: данные и механизм дешифрования лежат в отдельных местах.
Если механизм дешифрования это встроенная функция в той же базе, то:
- не копируй эту функцию на диск, который потом забывашь в гостиничном номере.
- если база работат в "прямом эфире", то в этом случае шифрование мало помогает?
Но Crazy, этим самым мы перечеркиваем не только утверждения популярных учебников, но и практику многих организаций.
Поэтому они наверно не используют хранимые функции, что бы расшифровывать данные.
Напрашивается такой вариант:
Механизм дешифрования кладем в отдельную утилиту которая работает через терминал и которую может использовать PHP.
Теперь злоумышленнику нужно получить доступ не только к базе, но и к этой утилите (что усложняет взлом).
Но утилита не дает той гибкости, которая дает хранимая MySQL функция при работе с базой в окошке терминала.
Здесь надо подумать.
_________________ Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
Последний раз редактировалось AlexShop 19 Июль 2008, 21:56:02, всего редактировалось 1 раз.
Шифрование имеет смысл если: данные и механизм дешифрования лежат в отдельных местах.
Я что-то торможу совсем. Данные и механизм дешифрования конечно могут быть в одном месте. Ключ должен храниться отдельно.
Передавать ключ MySQL функции, каждый раз при запросе - это лишний раз светить его
Если база может читать ключ от куда-то, то опять возвращаемся к прежней проблеме: получивший доступ к базе читает зашифрованные данные.
_________________ Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
Я думаю нормальные организации кладут ключ в программу и компилируют ее. В случае с PHP это может быть Zend Encoder.
Данные в базе зашифрованны этим ключем.
Читать зашифрованные данные в базе используя терминал можно через специально созданную (скомпилированную) программу.
_________________ Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
1. Данные в базе зашифрованны.
2. Ключ лежит в PHP.
3. Если злоумышленник получил доступ к базе, но не к PHP файлам - читать базу он не может.
Все идет по классической схеме, правда? Теперь сюжет:
4. Apache падает, PHP не работает. Мне надо получить доступ к зашифрованным данным в базе используя только терминал.
5. Я логинюсь в базу и получаю доступ к зашифрованным данным.
6. Не забываем что злоумышленник тоже имеет доступ к зашифрованным данным. Только он не знает как их расшифровать.
Как я работаю с базой через терминал и расшифровываю данные?
7. Я помню ключ
8. Я записываю ключ в MySQL переменную или временную таблицу (TEMPORARY TABLE)
9. Временные таблицы (и надеюсь переменные тоже) создаются отдельно для каждого соединения с базой. Злоумышленник не может их видеть.
10. Хранимая MySQL функция читает ключ из переменной и расшифровывает мне данные.
11. Злоумышленник по прежнему ничего не видит, кроме абра-кадабры
Вот она схема! Ну не даром же потратил время на этот топик
_________________ Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
Это называется "Security through obscurity". "Злоумышленик не войдет в мой дом, поскольку не догадается поискать ключ под ковриком".
Иными словами ты говоришь что шифрование базы бесполезно потому что ключ открыто лежит в PHP?
Практика показывает что нельзя построить 100% защиту от хакеров. И немалую роль тут играет человеческий фактор.
Защита строится из барьеров и препятствий на пути хакера.
Когда преодолевание этих барьеров стоит дороже, чем засекреченная информация - защита адекватная.
Я так думаю
_________________ Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
Хорошо, вот один вариант на вскидку.
Что если пароль для подключения к базе будет записан не в PHP файле, а в куках?
Итак сценарий:
- пароль к базе лежит в куках зашифрованный
- PHP скрипт читает куку
- PHP расшифровывает куку (алгоритм расшифровки может быть открытым, это не поможет хакеру)
- полученый из куки пароль PHP использует для подключения к базе
Как пароль попал в куку:
- при авторизации пользователь использует известный только ему пароль
- на основе этого пароля генерируется ключ (так как пароль может быть слабым)
- ключ шифруется, записывается в куку и используется для подключения к базе
Пользователь может знать, что на основе его пароля, генерируется ключ и используется для подключения к базе.
Пользователь может сам подключиться к базе, без вебсайта.
MySQL имеет очень хорошую систему привилегий. С помощью VIEW пользователей можно ограничивать что они видят в таблице по вертикали (столбики) так и по горизонтали (строки). С помощью хранимых процедур можно разрешить менять данные, в зависимости от того кто подключился к базе.
Пользователь подключившись к базе (напрямую) не должен увидеть/сделать ничего такого, чего он не смог бы увидеть/сделать через вэб-сайт.
Как практически такое сделать, еще не знаю.
Хранимые процедуры и VIEW должны менять свое поведение в зависимости от того кто подключился к базе.
Регистрация новых пользователей должна быть легкой.
Попробую как нибуть сделать простой пример. Если получится выложу для тестирования на прочность.
_________________ Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
16 Сообщения: 140 Зарегистрирован: 12.08.06 Откуда: Украина
Добавлено: 20 Июль 2008, 18:13:15
Включите, пожалуйста, 3-й микрофон, тут есть альтернативное мнение... Включили? Спасибо.
Итак, по-порядку:
1. Когда мне говорят о триггерах, курсорах, view's и прочих атрибутах нормальных СУБД в контексте MySQL - я радуюсь, что у нас не продаются молотки с вмонтированной отверткой. Если кратко, то - не для тех задач писан фришный мускуль. Если надо расширенно - я могу и расширенно, но потом.
2. AlexShop, ну ей богу, про АОП интереснее было. Ну не уперся никому ваш пароль для доступа в БД, и неважно, где он будет шифроваться - в пхп или не в пхп. Злоумышленнику нужна будет САМА БД. и если он сможет слить файл с физического диска - он его сольет и без пароля, подкрутит к своему движку и достанет все, что ему надо.
3. Я не против мускуля, я против фейерии "новых фич", которые повергают индусов в дикий ужас, а наших, падких до нового, программистов - в детский восторг. Так и представляю себя влетающего ко мне кодера с криком:"Мужик, я узнал, что данные в базе можно шифровать! Давай все зашифруем, чтобы никто не узнал!". Я не говорю, про то, что из БД процессингового центра мне не нужен пароль админа, мне нужны данные транзакций(попробуй их зашифруй). Я не говорю про то, что расшифровка - ресурсоемкая процедура. Нет, я говорю о простой вещи - о TCO. Ну почитайте вы книги, пойдите на курсы, в ВУЗЫ, в конце концов. Это все поддается нормальному планированию, расчету. Зачем тут детей баламутить?
AlexShop писал(а):
Тогда почему люди шифруют содержимое баз данных?
Кто, ну кто все эти люди?
_________________ Не можешь вынести хамства? Сосчитай до десяти и вынеси хама.
Если кратко, то - не для тех задач писан фришный мускуль. Если надо расширенно - я могу и расширенно, но потом.
PHP тоже не писался для сегодняшних задач. Так сложилось что мы имеем популярную заточку для вэба - LAMP. Потратив годы на изучение LAMP, я могу только приветствовать его дальнейшее развитие.
Задачи которые ставятся перед LAMP разработчиком самые тривиальные, например: как хранить номера кредитных карт?
_________________ Тот, кто задает вопрос, глупец в течение пяти минут, тот, кто его не задает, глупец всю свою жизнь. (Китайская поговорка)
Задачи которые ставятся перед LAMP разработчиком самые тривиальные, например: как хранить номера кредитных карт?
Правильный ответ: для секьюрного хранения номера кредитной карты нет ни смысла, ни пользы просто шифровать базу данных. Если хочется узнать, как по-уму организуется работа с такими данными -- посмотри, на каких принципах существует Kerberos.
16 Сообщения: 140 Зарегистрирован: 12.08.06 Откуда: Украина
Добавлено: 20 Июль 2008, 21:16:00
AlexShop писал(а):
PHP тоже не писался для сегодняшних задач. Так сложилось что мы имеем популярную заточку для вэба - LAMP.
Не то постулируем. В случае с СУБД это неприемлемо. До(!) триггеров и хранимых процедур надо получить нормальный бэкап. Под нормальным я понимаю следующее: инкрементальный, разностный, полный - не нарушающий нормальной работы БД. Плюс - доступ к журналу транзакций. А не приделывать к молотку отвертку. Если вы этого не понимаете - то годы потраченные на майскл не окупились ниразу. Деньги тут не в счет. Мы же не кодинг обсуджаем, в конце концов.
AlexShop писал(а):
Организация шифрует данные от своих (нечистоплотных) админов БД.
Спасибо, что напомнили. Значит, помимо бекапа, надо еще нормально сделать хранение прав доступа в бд. И шифрование данных тут нипричем. Вы про GRANT слышали?
_________________ Не можешь вынести хамства? Сосчитай до десяти и вынеси хама.
AlexShop, ты опять пошел не в ту сторону. Не нужно использовать Керберос. Нужно ПОНЯТЬ, как он работает и для чего его так сделали. Модули к PHP для этого не требуютмя. Требуется найти описание и ВДУМЧИВО его прочесть. Несколько раз. До наступления понимания.
AlexShop, в базах нет понятия "ROOT привелегии". Может быть, тебе все же книжки почитать? Там всякие умные слова есть. Пока не изучишь хотя бы эти слова -- тебя не будут понимать.
Что до шифрования базы -- я вижу, ты не последовал моему совету:
Цитата:
BTW, твоим способом она не решается. Ты сразу сможешь это понять, если от абстрактных нечистоплотных админов перейдешь к рассмотрению конкретных атак.
Уровень доступа: Вы не можете начинать темы. Вы не можете отвечать на сообщения. Вы не можете редактировать свои сообщения. Вы не можете удалять свои сообщения. Вы не можете добавлять вложения.