Защита данных в хранилище данных приложения google

17

В нашем приложении для Google App Engine хранится достоверное количество личной информации (электронная почта, ssn и т. д.) для идентификации пользователей. Я ищу советы о том, как защитить эти данные.

Моя текущая стратегия

Хранить конфиденциальные данные в двух формах:

  • Хешинг - использование SHA-2 и соли
  • Шифрование - использование открытого / закрытого ключа RSA

Когда нам нужно посмотреть вверх:

  • Выполнять поиск хэшированных данных (хешировать PII в запросе, сравнивать его с хэшированным PII в хранилище данных).

Если нам когда-либо понадобится повторно использовать данные или иначе обрабатывать их в необработанном виде:

  • Расшифруйте зашифрованную версию с помощью нашего закрытого ключа. Никогда не храните его в необработанном виде, просто обрабатывайте его, а затем повторно-хэш и amp; повторно зашифровать его.

Мои проблемы

Сохранение нашей секретной соли хешей

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

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

В промежутках между развертываниями солевой файл живет на USB-ключ, защищенный сердитым медведем (или сейфом).

С солью, живущей только в двух местах

  1. Клавиша USB
  2. Развернуто для приложений Google.

и с полной загрузкой кода, я не могу придумать, как кто-то может получить соль, не крадя этот USB-ключ. Я что-то пропустил?

Сохранение секретности секретного ключа RSA

Меньше беспокоиться об этом. Редко будет нужно расшифровать зашифрованную версию (только если мы изменим хэш-алгоритм или формат данных).

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

Мы можем хранить наш секретный ключ RSA на USB-накопителе, охраняемом медведем и тигром, и выводить его только тогда, когда нам это нужно.

Я понимаю, что этот вопрос не совсем специфичен для Google Apps, но я думаю, что GAE делает ситуацию несколько уникальной.

Если бы у меня был полный контроль, я бы делал такие вещи, как блокирование доступа к развертыванию и доступ к средству просмотра хранилища данных с двухфакторной аутентификацией, но эти параметры недоступны в данный момент (наличие специального пароля GAE хорош, но мне нравится иметь токены RSA).

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

    
задан Rob Boyle 10.04.2012 в 22:50
источник
  • вам нужно убедиться, что remote_api не включен. –  Shay Erlichmen 10.04.2012 в 23:10
  • Обязательно сделайте это @shayerlichmen, но меня беспокоит то, что если кто-то получит права администратора, они могут включить remote_api, даже если я ранее отключил его. –  Rob Boyle 10.04.2012 в 23:14
  • соли не секрет! Соль представляет собой случайное значение, добавляемое к каждому фрагменту хэшированных данных - другое для каждого элемента, используемое для предотвращения предвычисляющих атак. Если это одинаково для каждой части данных и секрет, это ключ - и вы должны использовать HMAC, а не сырую хеш-функцию. –  Nick Johnson 11.04.2012 в 03:21
  • Кроме того, вы можете заблокировать доступ к развертыванию и доступ к хранилищу данных с двухфакторной аутентификацией. Просто попросите, чтобы каждый, у кого есть доступ администратора к вашему приложению, включал двухфакторную аутентификацию в своей учетной записи Google. –  Nick Johnson 11.04.2012 в 03:23
  • Спасибо @NickJohnson, не понимал, что двухфакторный работал и для развертывания. Включение двухфакторного прямо сейчас! –  Rob Boyle 11.04.2012 в 20:36

3 ответа

11

При принятии решения о архитектуре безопасности первое, что в вашем уме всегда должно быть моделями угроз. Кто ваши потенциальные злоумышленники, каковы их возможности и как вы можете защищаться от них? Без четкого представления о вашей модели угроз у вас нет возможности оценить, достаточны ли ваши предлагаемые меры безопасности или даже если они необходимы.

Из вашего текста, я предполагаю, что вы пытаетесь защитить от некоторого подмножества следующих элементов:

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

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

Вы справедливо замечаете некоторые опасения по поводу хэширования данных с ограниченным количеством энтропии - и вы правы, чтобы их беспокоило. В какой-то степени соли могут помочь в этом, предотвращая атаки прекоммутации, а растяжение ключей, например, используемое в PBKDF2, scrypt и bcrypt, может сделать жизнь вашего злоумышленника более сложной, увеличив объем работы, которую они должны выполнять. Однако, с чем-то вроде SSN, ваше пространство ключей просто настолько мало, что никакое количество растягивания ключей не поможет - если вы хэш-данные и злоумышленник получает хэш, они смогут определить исходный SSN.

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

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

Конечно, способ номер один для защиты данных ваших пользователей состоит в том, чтобы не хранить его в первую очередь, если можно. :)     

ответ дан Nick Johnson 11.04.2012 в 03:38
  • Спасибо @ Ник, это очень полезно. К сожалению, не хранить данные не вариант, это ядро ​​для нашей бизнес-модели =) –  Rob Boyle 11.04.2012 в 20:44
  • Великая точка зрения, что если это одно и то же везде и в тайне, это ключ. Хеширование было привлекательным, потому что было легко запустить запрос - я передал данные входящего запроса с солью (отлично, ключ) и сравнил его с хешированными данными в хранилище данных. Но если у меня есть шифр, который обеспечивает согласованный шифрованный текст, это тоже сработает. Я действительно беспокоюсь о том, что у меня есть ключ, чтобы разблокировать данные и сами данные, все из которых живут на движке приложения сразу ... Я чувствовал себя хорошо, знаю, что даже если кто-то получит наш хранилище данных и код, они, по крайней мере, должны будут выполнить НЕКОТОРЫЕ РАБОТЫ для перебора хэшированных данных. –  Rob Boyle 11.04.2012 в 20:52
3

Вы можете повысить свою безопасность алгоритма хеширования, используя HMAC, секретный ключ и уникальную соль для каждой записи (я знаю, что люди будут не согласны со мной по этому поводу, но я убежден в своих исследованиях, что это помогает избежать определенных атак). Вы также можете использовать bcrypt или scrypt для хэша, который сделает реверсирование хэша чрезвычайно трудоемким процессом (но вам также придется учитывать это, поскольку время, затрачиваемое вашим приложением на вычисление хэша).

Отключив загрузку кода и сохраняя секретный ключ, я не могу представить, как кто-то может его удержать. Просто убедитесь, что ваш код защищен подобными безопасными охранниками или что вы удаляете секретный ключ из своего кода во время разработки и только вытаскиваете его для развертывания. Я предполагаю, что вы сохраните свой секретный ключ в своем коде (я слышал, что многие говорят, что держать его в памяти очень надежно, но учитывая природу AppEngine и экземпляров, это невозможно).

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

    
ответ дан someone1 11.04.2012 в 00:38
  • Google разрешает двухфакторную аутентификацию для учетных записей, но, к сожалению, не для движка Google. –  Rob Boyle 11.04.2012 в 01:56
  • @RobBoyle Да, да! Если ваша учетная запись использует двухфакторный авторизатор, вам либо нужно использовать специальный пароль для приложения, либо вы можете пройти стандартный двухфакторный танец, передав флаг --oauth2 в appcfg.py. –  Nick Johnson 11.04.2012 в 03:27
  • Whoa! Это круто, я не заметил флаг --oauth2. Это потрясающе. Спасибо @NickJohnson. –  Rob Boyle 11.04.2012 в 19:48
1

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

Точное зернистое хеширование означает, хэш последовательных байтов потока данных для получения накопленного хеша. iee (abcd) = hash (a, b) + hash (b, c) + и т. д. Этот тип хэширования будет определять, насколько похожи исходные данные, а не совпадение.     

ответ дан Harisankar Krishna Swamy 07.07.2013 в 20:12
  • Мы просто делали простые точные совпадения, нам не нужно было сортировать; так что просто прямое сравнение. –  Rob Boyle 09.07.2013 в 01:04