Стратегия сохранения секретной информации, такой как ключи API, из-за контроля источника?
Я работаю над веб-сайтом, который позволит пользователям регистрироваться с использованием учетных данных OAuth от подобных Twitter, Google и т. д. Для этого мне нужно зарегистрироваться у этих разных провайдеров и получить суперсекретный ключ API что я должен защищаться с обещаниями против различных частей тела. Если мой ключ сгруппирован, часть будет дергаться.
Ключ API должен перемещаться вместе с моим источником, поскольку он используется во время выполнения для выполнения запросов на аутентификацию. В моем случае ключ должен существовать в приложении в файле конфигурации или внутри самого кода. Это не проблема, когда я создаю и публикую с одной машины. Однако, когда мы бросаем исходный контроль в микс, все усложняется.
Как я дешевый ублюдок, я бы предпочел использовать бесплатные службы управления версиями, такие как TFS в облаке или GitHub. Это оставляет мне небольшую загадку:
Как я могу сохранить свое тело в целости, когда ключи моего API находятся в моем коде, а мой код доступен в открытом репозитории?
Я могу придумать несколько способов справиться с этим, но ни один из них не удовлетворяет.
- Я могу удалить всю личную информацию из кода и отредактировать ее после развертывания. Это было бы серьезной болью для реализации (я не буду подробно описывать многие способы), и это не вариант.
- Я мог бы зашифровать его. Но поскольку я должен расшифровать его, любой, у кого есть источник, может понять, как это сделать. Бессмысленно.
- Я мог бы заплатить за контроль частного источника. LOL j /k тратит деньги? Пожалуйста.
- Я мог бы использовать языковые функции, чтобы отделить важную информацию от остальной части моего источника и, следовательно, сохранить ее от источника. Это то, что я делаю сейчас, но его можно было легко надуть, ошибочно проверив секретный файл.
Я действительно ищу гарантированный способ гарантировать, что я не разделяю своих рядовых с миром (кроме snapchat), который будет работать плавно через разработку, отладку и развертывание и быть уверенным в надежности. Это совершенно нереально. Итак, что реально можно сделать?
Технические детали: VS2012, C # 4.5, управление версиями либо будет сервисом TF, либо GitHub. В настоящее время используется частичный класс для разделения секретных ключей в отдельном файле .cs, который не будет добавлен в исходный код. Я думаю, что у GitHub может быть преимущество, поскольку .gitignore можно использовать для обеспечения того, чтобы частичный файл класса не был проверен, но я до этого догадался. Я надеюсь, что «о, общая проблема, это то, как вы это делаете», но мне, возможно, придется согласиться на «это не всасывает столько, сколько могло бы быть»,: /
12 ответов
Не помещайте свою секретную информацию в свой код. Поместите его в файл конфигурации, который считывается вашим кодом при запуске. Конфигурационные файлы не следует вводить в элемент управления версиями, если только они не являются «заводскими настройками по умолчанию», а затем у них не должно быть личной информации.
См. также вопрос Контроль версий и файл личной настройки для как это сделать хорошо.
Вы можете поместить все частные /защищенные ключи в качестве переменных системной среды. Ваш файл конфигурации будет выглядеть следующим образом:
private.key = # {systemEnvironment [ 'private_key']}
Вот как мы обрабатываем эти случаи, и ничего не происходит в коде. Он отлично сочетается с различными файлами и профилями свойств. Мы используем разные файлы свойств для разных сред. В нашей локальной среде разработки мы добавили ключи разработки в файлы свойств, чтобы упростить локальную настройку:
private.key = A_DEVELOPMENT_LONG_KEY
Pure Git way
-
.gitignore
включен файл с частными данными - Используйте локальную ветвь, в которой вы заменяете
TEMPLATE
наDATA
- Используйте фильтры smudge /clean, в которых скрипт (локальный) фильтра выполняет двунаправленную замену
TEMPLATE
<->DATA
Меркуриальный путь
- MQ-patch (ов) поверх фиктивного кода, которые заменяют
TEMPLATE
наDATA
(изменения общедоступны, патч является закрытым) - Расширение ключевого слова со специально разработанными ключевыми словами (расширенное только в рабочем каталоге )
SCM-агностический способ
- Заменить ключевые слова как часть процесса сборки /развертывания.
Это особенность Android /Gradle, но вы можете определить ключи в своем глобальном файле gradle.properties
, расположенном в домашнем пользователе /.gradle /
. Это также полезно, так как вы можете использовать различные свойства в зависимости от типа buildType или API-интерфейса i.e для разработчиков и другого для выпуска.
gradle.properties
MY_PRIVATE_API_KEY = 12356abcefg
build.gradle
buildTypes {
отлаживать{
buildConfigField ("String", "GOOGLE_VERIFICATION_API_KEY", "\" "+ MY_PRIVATE_API_KEY +" \ "")
minifyEnabled false
applicationIdSuffix ".debug"
}
}
В коде вы ссылаетесь как на
Строка myAPI = BuildConfig.GOOGLE_VERIFICATION_API_KEY;
Я вложил секреты в зашифрованный файл (ы), который я затем совершил. Фраза pass предоставляется при запуске системы или хранится в небольшом файле, который я не совершаю. Приятно, что Emacs будет радостно управлять этими зашифрованными файлами. Например, файл инициализации emacs включает в себя: (load «secrets.el.gpg»), который просто работает - запрос пароля для тех редких случаев, когда я запускаю редактор. Я не беспокоюсь о том, что кто-то нарушает шифрование.
Вы не должны распространять этот ключ с вашим приложением или хранить его в репозитории исходного кода. Этот вопрос спрашивает, как это сделать, и это не то, что обычно делается.
Мобильное веб-приложение
Для Android /iPhone устройство должно запрашивать KEY с вашего собственного веб-сервиса, когда приложение запускается впервые. Затем ключ хранится в безопасном месте. Если ключ будет изменен или отменен издателем. Ваш веб-сервис может опубликовать новый ключ.
Хостинг веб-приложений
Клиенты, использующие лицензию вашего программного обеспечения, должны вручную вводить ключ при первой настройке программного обеспечения. Вы можете дать всем один и тот же ключ, разные ключи или получить свои собственные.
Опубликованный исходный код
Вы храните исходный код в публичном репозитории, но не KEY. В конфигурации файла вы добавляете строки * здесь. . Когда разработчик использует ваш исходный код, они делают копию файла sample.cfg
и добавляют свой собственный ключ.
Вы не храните файл config.cfg
, используемый для создания или производства в репозитории.
Используйте переменные среды для секретных вещей, которые изменяются для каждого сервера.
http://en.wikipedia.org/wiki/Environment_variable
Как использовать их зависит от языка.
Я думаю, что это проблема, с которой в какой-то момент были проблемы.
Вот рабочий процесс, который я использовал, который может сработать для вас. Он использует .gitignore с завихрением:
- Все файлы конфигурации входят в специальную папку (файлы конфигурации с образцом - необязательно)
- Все файлы конфигурации включены в .gitignore, чтобы они не публиковали
- Настройте сервер gitolite (или ваш любимый git-сервер) в личном ящике
- Добавить репо со всеми конфигурационными файлами на закрытом сервере
- Добавить скрипт для копирования файлов конфигурации в специальную папку в основном репо (необязательно)
Теперь вы можете клонировать конфигурационное репо для любой системы разработки и развертывания. Просто запустите сценарий, чтобы скопировать файлы в нужную папку, и все готово.
Вы все еще получаете все конфеты GitHub, делитесь своим кодом с миром, и конфиденциальные данные никогда не находятся в основном репо, поэтому они не публикуются. Они все еще остаются только притяжением и копией от любой системы развертывания.
Я использую 15 $ /year box для частного git-сервера, но вы также можете настроить его дома, по требованию cheapskate; -)
PS: Вы также можете использовать подмодуль git ( http://git-scm.com/docs /git-subodule ), но я всегда забываю команды, поэтому быстро и amp; грязные правила!
Используйте шифрование, но предоставляйте мастер-ключ при запуске в качестве пароля на консоли, в файле, который может прочитать только пользователь процесса, или из системного хранилища ключей, такого как Keychain для Mac OS или хранилища ключей Windows.
Для непрерывной доставки вам понадобятся различные ключи, записанные где-то. Конфигурация должна быть отделена от кода, но имеет смысл держать ее под контролем версий.
3 Стратегии, еще не упомянутые (?)
При проверке или в предварительном проверке VCS в hook
- поиск строк с высокой энтропией, example- обнаружение-секреты
- regex ищет известные шаблоны ключей API. В качестве примера можно привести клавиши AKIA * AWS, git-secrets - это один из инструментов, основанных на этом. Кроме того, имена переменных, такие как «пароль» с постоянным присваиванием.
- найдите известные секреты - вы знаете свои секреты, найдите текст для них. Или используйте инструмент, я написал это доказательство концепции .
Уже упомянутые стратегии
- хранить в файле вне исходного дерева
- Имейте это в исходном дереве, но скажите VCS, чтобы игнорировать его
- переменные окружения - это вариация сохранения данных вне исходного дерева.
- просто не дают ценные секреты разработчикам
Храните личную информацию вне своего источника. Создайте незагруженный по умолчанию для распространения, и ваш VCS проигнорирует реальный. Процесс установки (будь то manual, configure /build или wizard) должен обрабатывать создание и заполнение нового файла. При необходимости измените разрешения на файл, чтобы убедиться, что только этот пользователь (веб-сервер?) Может его прочитать.
Преимущества:
- Не предполагает создание объекта разработки == производственный объект
- Не предполагает, что всем обозревателям кодов /проверкам кода доверяют
- Предотвращение простых ошибок, сохраняя его вне контроля версий.
- Легко автоматизировать установку с настраиваемой конфигурацией для QA /build
Если вы уже делаете это и случайно проверяете его, добавьте его в .gitignore
вашего проекта. Это сделает невозможным повторение.
Там есть множество бесплатных Git-хостов, которые предоставляют частные репозитории. Хотя вы никогда не должны указывать свои учетные данные, вы можете быть дешевыми и иметь частные репозитории. ^ _ ^
Вместо того, чтобы ключ OAuth хранился как необработанные данные в любом месте, почему бы не запустить строку через некоторый алгоритм шифрования и сохранить ее как соленый хеш? Затем используйте файл конфигурации, чтобы восстановить его во время выполнения. Таким образом, ключ не хранится нигде, независимо от того, хранится ли он в окне разработки или самом сервере.
Вы даже можете создать API таким образом, чтобы ваш сервер автоматически генерировал новый соленый и хэшированный ключ API для каждого запроса, таким образом, даже ваша команда не может видеть источник OAuth.
Изменить: возможно, попробуйте Crypto Library в Стэнфорде Javascript , это позволяет использовать довольно безопасное симметричное шифрование /дешифрования.