В настоящее время я работаю над проектом, который включает ежедневное извлечение данных (аптечных записей) из базы данных VisualFox Pro и загрузку некоторых из них на сайт WordPress, где клиенты аптеки могут безопасно его просматривать. Мне бы хотелось получить некоторые рекомендации в отношении общей методологии моего программного обеспечения – я могу его закодировать, но мне нужно знать, правильно ли я поеду. Я пишу как программное обеспечение для ПК (в C # /. NET 4.5), так и плагин PHP WordPress.
Текущий процесс шифрования сервера данных, который я планирую использовать, основан на этой статье . Подводя итог, он защищает шифрование данных каждого отдельного пользователя асимметрично своим собственным открытым ключом, хранящимся на сервере. Закрытый ключ для дешифрования этих данных затем сам зашифровывается симметрично с использованием пароля пользователя и сохраняется. Таким образом, даже если база данных украдена, хэш-код пользователя должен быть поврежден, и даже тогда процесс необходимо повторить для данных каждого пользователя.
Единственная слабость, на которую указывает сам автор, и главный вопрос моего вопроса, заключается в том, что во время входа пользователя в систему дешифрованный ключ хранится в хранилище сеансов. То, как предлагается статья, заключается в том, чтобы просто ограничить время входа пользователя в систему. Я думал, что лучшим решением будет хранить этот ключ в недолговечном безопасном файле cookie (конечно, весь процесс происходит через HTTPS) , Таким образом, если злоумышленник контролирует компьютер пользователя и может читать свои куки-файлы, он может, вероятно, просто заблокировать свой пароль и войти в систему, не нужно красть базу данных, хотя даже если злоумышленник получает доступ к серверу, они не могут расшифровать трафик HTTPS (или они могут?) Я не уверен.)
Должен ли я использовать безопасные файлы cookie или хранилище сеансов для временного хранения дешифрованного ключа?
Вторая вещь, которую я все еще хочу решить – хранить данные – это скорее проблема эффективности. Поскольку каждый пользователь имеет свой собственный ключ для шифрования, следует, что записи для каждого пользователя должны храниться отдельно. Я не знаю, должен ли я хранить «блок» данных для каждого пользователя, содержащий зашифрованный JSON с массивом объектов, представляющих записи, или должен ли я хранить записи в таблице с фактической структурой данных и шифровать каждое поле данных отдельно с ключом.
Я склоняюсь к хранению данных как одного блока – мне кажется, что более эффективно расшифровывать один большой блок данных за раз, чем, возможно, несколько тысяч отдельных полей. Кроме того, даже если я сохраню данные в своей надлежащей структуре, я все равно не смогу использовать WHERE, ORDERBY и т. Д. MySQL, поскольку все данные будут BLOB.
Должен ли я хранить данные как большой блок для каждого пользователя или разделяться на разные поля?
Я извлекаю данные из файла DBF и по существу делаю «diff», в результате чего я сравниваю текущие данные из данных последнего дня и загружаю только блоки пользователей, которые изменились (я могу не только загружать записи , так как я, вероятно, в конечном итоге сохраню данные пользователей в блоках). Я также включаю инструкции «удалить» для пользователей, которые были удалены. Это так же, как и сотни тысяч записей в базе данных, общая сумма которых превышает 200 мб, и размер увеличивается с каждым днем.
Мой текущий план состоит в том, чтобы записать все эти данные в файл JSON, gzip и загрузить его на сервер. Мой вопрос: как мне это сделать, обеспечивая безопасность данных? Естественно, загрузка будет происходить через HTTPS, и у меня есть пароль API, чтобы разрешать разрешенные загрузки, но моя главная проблема заключается в том, как защитить данные, если сервер взломан. Я не хочу, чтобы злоумышленник просто хватал JSON-файл с сервера во время его обработки. Одна из моих идей заключалась в том, чтобы заставить сервер отправлять мне список открытых ключей для пользователей и выполнять шифрование в моем программном обеспечении до загрузки. Мне кажется, что это единственный способ защитить эти данные. Я мог бы зашифровать весь файл в формате JSON, возможно, с помощью ключа API или специальный пароль, но это спорный вопрос, если злоумышленник может получить доступ только расшифрованный файл, как он обрабатывается на сервере. Это хорошее решение?
Должен ли я шифровать данные отдельно на стороне клиента или есть способ безопасно передать его на сервер и зашифровать его там?
Заранее благодарю за любые ответы, я бы хотел услышать от кого-то, кто раньше сталкивался с такими проблемами.
Примечание: перекрестная ссылка на программистов , см. Комментарии.
Как бы то ни было, я работаю над подобной системой для шифрования личных данных (email, IP) в комментариях WordPress, так что, если сервер взломан, конфиденциальные данные в базе данных все еще зашифрованы. Сохранение ключа ассиметричного дешифрования в сеансе было для меня, так как это могло оставить ключ на сервере, чтобы злоумышленник мог захватить одновременно с их компрометацией.
Таким образом, файлы cookie через SSL-сертификат – лучший способ пойти – по крайней мере, злоумышленник должен ждать, пока пользователь войдет в систему, прежде чем они смогут украсть свой ключ (ы). В сочетании с этим, какая-то система tripwire была бы хорошей идеей, так что пользователи не смогут войти в систему (тем самым предоставив свои ключи ожидающему злоумышленнику), как только она будет скомпрометирована.
Как вы говорите, шифрование записей (либо с одним ключом в соответствии с моим дизайном, либо с несколькими ключами в соответствии с вашим) означает, что поиск по записям становится процессом, который вы должны удалять с сервера базы данных, что по очереди означает, что он будет значительно помедленнее.
Вы можете смягчить это, сделав компромисс между скоростью и безопасностью: некоторые поля могут быть пушистыми, а затем сохранены в незашифрованном виде. Например, если вы хотите найти, где находятся ваши пациенты, получить их (lat, long) со своего адреса, применить к нему случайный сдвиг (скажем, до трех миль по обеим осям в любом направлении), а затем сохранить полученные координаты в виде простого текста. Приблизительные запросы счетчика, относящиеся к местоположению, могут быть выполнены без расшифровки.
В приведенном выше примере рассматривается, как уменьшить атаки против сервера, что является вашим самым большим риском, поскольку у вас есть все ваши записи, хранящиеся там. Как вы правильно заметили, атаки на клиентские машины также вызывают беспокойство, и если они являются членами общественности, то их процессы безопасности можно считать несуществующими.
Исходя из этого, вы можете укрепить единый пароль (который дается в целом) с парольной фразой, из которой клиенту нужно выбрать три случайные буквы (т. Е. Конкретно не дано в целом). Это элегантно защищает от клавиатурных шпионов двумя способами: во-первых, выпадающие меню используются, которые труднее подслушивать, и даже если пользователь использует быстрые клавиши, они не предоставили полную фразу. При каждом успешном входе индекс случайных букв (например, 1, 4 и 5) записывается и не запрашивается снова в течение длительного периода. Очевидно, что слишком много неправильных ответов заставляет заблокировать учетную запись и требует повторной авторизации через телефонный звонок или код сброса улитки.
Другие методы проверки подлинности, которые вы могли бы использовать: введите пользователю дополнительную кодовую фразу при каждом вводе правильного пароля или (возможно, чрезмерно дорого) используйте устройство аутентификации в соответствии с онлайн-банковским переводом.
Еще один совет для безопасности – хранить как можно меньше личной информации. Если вы можете обойтись без возможности немедленного сброса паролей по электронной почте, то, пожалуй, необязательно назвать имя, адрес, номера телефонов и электронную почту – все личные данные. Эта личная информация может храниться отдельно в отключенной базе данных на другом сервере, используя общий первичный ключ, чтобы связать их вместе. (Фактически, если пользователь хочет сбросить свой пароль, вы можете просто сохранить флаг с их анонимной пользовательской записью, и аптекарь может запустить процесс сброса вручную на своем брандмауэре, когда они посещают административную панель).
Должны ли вы шифровать табличные данные в одном блобе или оставить его в каждом столбце? Я также рассмотрел этот вопрос в своем приложении. Для меня я сохранил его в одном блоке, поскольку мой прецедент является интенсивным с поиском и имеет N расшифровок на строку, а не один, что упростило решение. Тем не менее, вы можете предпочесть чистоту шифрования столбцов по отдельности, и можно утверждать, что если коррупция ползет, разделение их дает вам больше шансов, что некоторые из строк выживут.
Если вы решили сохранить в одном блоке, я использую формат, подобный этому (строки, разделенные символами новой строки, до того, как они будут асимметрично зашифрованы):
1.2 <-- version of this format, so I can add things in the future key1=value1 key2=value2 ...
Если у вас есть несколько процессов, которые записываются в столбцы, убедитесь, что вы блокируете строки между чтением и записью, иначе (как намечено выше) вы можете потерять некоторые ваши данные.
Как вы говорите, это в равной степени может быть JSON, если этот формат лучше для вас.
Мое понимание этого вопроса: как вы копируете незашифрованную автономную копию, учитывая, что вы не можете самостоятельно расшифровывать записи пользователей? Интересно, можете ли вы немного уменьшить свои ограничения безопасности и сохранить общий открытый ключ на сервере и сохранить отдельную запись изменений, зашифрованных с помощью общего ключа. Это будет заполнять таблицу, которая должна периодически очищаться (путем запуска процедуры синхронизации на удаленной защищенной машине); таким образом, значение таблицы изменений для злоумышленника будет малым по сравнению с тем, чтобы получить всю незашифрованную базу данных.
Разумеется, соответствующий секретный ключ должен находиться на компьютере фармацевта, снова надежно защищенном от Интернета.
Риск с этим дизайном заключается в том, что злоумышленник заменяет открытый ключ сервера одним из своих собственных, чтобы впоследствии они могли собирать информацию, которая была зашифрована только для них! Однако до тех пор, пока вы установили проводку на сервере, это может быть разумно защищено: если это вызвано, динамическая часть веб-приложения не будет писать никаких новых изменений (на самом деле не будет работать на всех), пока система не будет отсканирована и не будет определена как безопасная.