Как защитить ключи OAuth от пользователя, декомпилирующего мой проект?

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

Могу ли я реагировать или это настоящая проблема (с известным решением) для настольных приложений?

Этот проект кодируется на Java, но я также разработчик С#, поэтому любые решения для .NET тоже будут оценены.

EDIT: Я знаю, что нет идеального решения, я просто ищу смягчающие решения.

EDIT2: Я знаю, что в основном только решение использует некоторую форму обфускации. Есть ли свободные поставщики для .NET и Java, которые будут выполнять обфускацию строк?

Ответ 1

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

Есть причины, по крайней мере, приложить минимальные усилия для защиты себя.

Минимальная сумма усилий не будет эффективной. Даже максимальная сумма усилий не будет эффективной против квалифицированного инженера-реверсора/хакера всего за несколько часов свободного времени.

Если вы не хотите, чтобы ваши ключи OAuth были взломаны, не помещайте их в код, который вы распространяете среди ненадежных пользователей. Период.

Могу ли я реагировать или это настоящая проблема (с известным решением) для настольных приложений?

Это настоящая проблема без известного (эффективного) решения. Не в Java, а не в С#, а не в Perl, а не в C, ни в чем. Подумайте об этом, как если бы это был Закон физики.


Ваши альтернативы:

  • Принудительно использовать доверенную платформу, которая будет выполнять только шифрованный код. (Подсказка: это скорее всего не практично для вашего приложения, потому что компьютер с текущим поколением не работает таким образом. И даже TPS можно взломать при правильном оборудовании.)

  • Превратите ваше приложение в службу и запустите его на машине/машинах, к которым вы контролируете доступ. (Подсказка: похоже, что OAuth 2.0 может удалить это требование.)

  • Использовать механизм аутентификации, который не требует распространения постоянных секретных ключей.

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


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

И игнорируя тот факт, что аргумент по аналогии необоснован, эта конкретная аналогия распадается по следующей причине. Физические замки не являются непроницаемыми. Замок на вашей входной двери "работает", потому что кто-то должен стоять перед вашим домом, видимым с дороги, прокручивающей ваш замок на минуту или около того... или ударяя его большим молотом. Кто-то делает это, рискует, что он/она будет соблюден, и полиция будет вызвана. Банковские хранилища "работают", потому что время, необходимое для их проникновения, - это количество часов, а также другие аварийные сигналы, охранники и т.д. И так далее. В отличие от этого, хакер может тратить минуты, часы и даже дни, пытаясь нарушить ваши меры технической защиты, с фактически нулевым риском наблюдения/обнаружения.

Ответ 2

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

Я думаю, вы пытаетесь решить другую проблему. Если вы пытаетесь найти способ для сервера проверить, что только ваш клиентский код обращается к вашему серверу, вы столкнулись с очень большой задачей.

Ответ 3

Не важно, платформа, то, что вы просите, всегда будет невозможной. Независимо от того, что вы сделали, чтобы использовать эту функцию, что-то не так с вашим приложением. Вы никогда не сможете доверять клиенту, как это. Возможно, вы ищете (in) Security Through Obscurity.

Ответ 4

Изменить: Позвольте мне быть ясным; это не решение для безопасного хранения ваших ключей в двоичном коде, как многие другие упоминали, нет никакого способа сделать это. То, что я описываю, является методом смягчения некоторой опасности этого.

/Edit

Это лишь частичное решение, но оно может работать в зависимости от вашей настройки; он хорошо работал для нас в нашей внутренней сети университета.

Идея заключается в том, что вы делаете сервис, доступ к которому может получить только компьютер.

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

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

Мы сделали это для приложения Windows, которое использует хранилище данных учеников, которое, как вы можете себе представить, должно быть довольно безопасным.

Идея заключалась в том, что у нас был провайдер соединений, работающий как служба где-то, и у нас была система heartbeat, которая генерировала новый ключ каждые 30 секунд или около того.

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

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

Надеюсь, это вдохновит вас на какое-то решение!

Ответ 5

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