Если вы отправляете этот почтовый запрос в кросс-домен, вы должны проверить эту ссылку.
https://stackoverflow.com/a/1320708/969984
Ваш сервер не принимает запрос на перекрестный сайт. Поэтому необходимо изменить конфигурацию сервера, чтобы разрешить запросы на межсайтовый сайт.
-dontwarn com.dropbox.**
-keep class com.dropbox.** { *; }
Это подход грубой силы; вы можете уточнить такую конфигурацию, как только обработанное приложение будет работать. В конце концов, это экономический компромисс, который вы должны сделать: насколько важны ключи, сколько времени или программного обеспечения вы можете себе позволить, насколько изощренными являются хакеры, которые интересуются ключами, сколько времени они захотят потратить, сколько стоит задержка до взлома ключей, в каком масштабе будут успешными хакеры раздавать ключи и т. д. Небольшие фрагменты информации, такие как ключи, сложнее защитить, чем все приложения.
(я разработчик ProGuard и DexGuard)
Старая старая почта, но все же достаточно хорошая. Я думаю, что скрывать его в библиотеке .so было бы здорово, конечно, используя NDK и C ++. .so файлы можно просмотреть в шестнадцатеричном редакторе, но удача декомпилирует: P
Наиболее безопасным решением является сохранение ваших ключей на сервере и маршрутизация всех запросов, требующих этого ключа через ваш сервер. Таким образом, ключ никогда не покидает ваш сервер, поэтому, пока ваш сервер защищен, так и ваш ключ. Конечно, с этим решением стоит стоимость исполнения.
Немного идей, на мой взгляд, только первый дает некоторую гарантию:
Если вы хотите быстро взглянуть на то, как легко читать код apk, а затем захватить APKAnalyser:
http://developer.sonymobile.com/knowledge-base/tool-guides/analyse-your-apks-with-apkanalyser/
Одним из возможных решений является кодирование данных в вашем приложении и использование декодирования во время выполнения (когда вы хотите использовать эти данные). Я также рекомендую использовать progaurd, чтобы затруднить чтение и понимание декомпилированного исходного кода вашего приложения. например, я поместил закодированный ключ в приложение, а затем использовал метод декодирования в своем приложении для декодирования моих секретных ключей во время выполнения:
// "the real string is: "mypassword" ";
//encoded 2 times with an algorithm or you can encode with other algorithms too
public String getClientSecret() {
return Utils.decode(Utils
.decode("Ylhsd1lYTnpkMjl5WkE9PQ=="));
}
Декомпилированный исходный код защищенного приложения:
public String c()
{
return com.myrpoject.mypackage.g.h.a(com.myrpoject.mypackage.g.h.a("Ylhsd1lYTnpkMjl5WkE9PQ=="));
}
По крайней мере, для меня это достаточно сложно. это так я делаю, когда у меня нет выбора, кроме как сохранить значение в моем приложении. Конечно, мы все знаем, что это не лучший способ, но он работает для меня.
/**
* @param input
* @return decoded string
*/
public static String decode(String input) {
// Receiving side
String text = "";
try {
byte[] data = Decoder.decode(input);
text = new String(data, "UTF-8");
return text;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return "Error";
}
Декомпилированная версия:
public static String a(String paramString)
{
try
{
str = new String(a.a(paramString), "UTF-8");
return str;
}
catch (UnsupportedEncodingException localUnsupportedEncodingException)
{
while (true)
{
localUnsupportedEncodingException.printStackTrace();
String str = "Error";
}
}
}
, и вы можете найти так много классов шифрования с небольшим искать в google.
Единственный верный способ сохранить эти личные данные - сохранить их на своем сервере и отправить приложение на сервер, а сервер взаимодействует с Dropbox. Таким образом, вы НИКОГДА не распространяете свой закрытый ключ в любом формате.
Сохраните секрет в firebase database
и получите от него при запуске приложения. Это намного лучше, чем вызов веб-службы.
Мы можем использовать Gradle для защиты ключа API или секретного ключа.
1. gradle.properties (Свойства проекта): Создать переменную с ключом.
GoolgeAPIKey = "Your API/Secret Key"
2. build.gradle (Module: app): установите переменную в build.gradle для доступа к ней в активности или фрагменте. Добавьте ниже код в buildTypes {}.
buildTypes.each {
it.buildConfigField 'String', 'GoogleSecAPIKEY', GoolgeAPIKey
}
3. Получите доступ к нему в Activity / Fragment с помощью приложения BuildConfig:
BuildConfig.GoogleSecAPIKEY
Вышеупомянутое решение полезно в проекте с открытым исходным кодом для передачи по Git. (Спасибо Дэвиду Роусону и Риязи-Али за ваш комментарий).
Согласно комментариям Мэтью и Пабло Чегарры, вышеупомянутый способ небезопасен, и Декомпилятор позволит кому-то просмотреть BuildConfig с помощью наших секретных ключей.
Решение:
Мы можем использовать NDK для защиты API-ключей. Мы можем хранить ключи в собственном классе C / C ++ и обращаться к ним в наших классах Java.
Пожалуйста, следуйте этому блоку , чтобы защитить ключи API с помощью NDK.
Последующее наблюдение за тем, как безопасно хранить маркеры в Android
gradle.properties
не следует указывать в Git, поэтому это способ сохранить секрет из совершенного исходного кода, по крайней мере
– David Rawson
9 December 2017 в 10:40
apk
(он будет добавлен в сгенерированный файл BuildConfig
), хотя это определенно хорошая идея для управления различными ключами API (например, с открытым исходным кодом проект)
– riyaz-ali
8 March 2018 в 09:07
Другой подход заключается в том, чтобы не иметь секрет на устройстве в первую очередь! См. Методы безопасности мобильных API (особенно часть 3).
Используя традиционную косвенную традицию, поделитесь секретом между конечной точкой API и службой проверки подлинности приложения. Когда ваш клиент хочет вызвать вызов API, он просит службу аутентификации приложения аутентифицировать его (используя сильные методы удаленной аттестации) и получает ограниченный по времени (обычно JWT) токен, подписанный этим секретом. Маркер отправляется с каждым вызовом API, где конечная точка может проверить свою подпись перед действием по запросу.
Настоящий секрет никогда не присутствует на устройстве; на самом деле, приложение никогда не знает, действительно ли оно или нет, оно вызывает проверку подлинности и передает полученный результирующий токен.
Итак, если вы хотите защитить свой секрет, если вы когда-либо захотите изменить секрет, вы можете сделать это, не требуя от пользователей обновлять установленные приложения.
Итак, если вы хотите защитить свой секрет, не имея его в своем приложение в первую очередь является довольно хорошим способом.
Этот пример имеет несколько различных аспектов. Я упомянул пару моментов, которые, как я полагаю, не были явно рассмотрены в другом месте.
Защита секретности в пути
Первое, что нужно отметить, это доступ к API-интерфейсу Dropbox с использованием их механизм аутентификации приложений требует, чтобы вы передавали свой ключ и секрет. Соединение HTTPS означает, что вы не можете перехватить трафик, не зная сертификата TLS. Это делается для того, чтобы человек не перехватывал и не читал пакеты на своем пути с мобильного устройства на сервер. Для обычных пользователей это действительно хороший способ обеспечить конфиденциальность своего трафика.
То, на что это не удобно, мешает злоумышленнику загружать приложение и проверять трафик. Очень просто использовать прокси-сервер man-in-the-middle для всего трафика на мобильном устройстве и из него. Это не требует разборки или обратного проектирования кода, чтобы извлечь ключ приложения и секрет в этом случае из-за характера API Dropbox.
Вы могли бы выполнить pinning , который проверяет, что сертификат TLS, который вы получаете с сервера, является тем, который вы ожидаете. Это добавляет проверку клиенту и затрудняет перехват трафика. Это затруднило бы проверку трафика в полете, но проверка пиннинга происходит в клиенте, поэтому, вероятно, по-прежнему можно будет отключить тест пиннинга.
Защита секретности в покое
Как первый шаг, использование чего-то вроде proguard поможет сделать его менее очевидным, если любые секреты. Вы также можете использовать NDK для хранения ключа и секретности и отправки запросов напрямую, что значительно сократит количество людей с соответствующими навыками для извлечения информации. Дальнейшая обфускация может быть достигнута за счет сохранения значений непосредственно в памяти в течение какого-то времени, вы можете зашифровать их и дешифровать их непосредственно перед использованием, как предложено другим ответом.
Дополнительные параметры
Если вы сейчас параноик о том, чтобы хранить секрет в своем приложении, и у вас есть время и деньги, чтобы инвестировать в более комплексные решения, вы можете подумать о сохранении учетных данных на своих серверах (предположительно, что у вас есть). Это увеличило бы латентность любых вызовов API, поскольку оно должно будет связываться через ваш сервер и может увеличить затраты на обслуживание вашего сервиса из-за увеличения пропускной способности данных.
Затем вам нужно решить, как лучше всего общаться с серверами, чтобы обеспечить их защиту. Это важно для предотвращения повторения всех тех же проблем с вашим внутренним API. Лучшее эмпирическое правило, которое я могу дать, - это не передавать какой-либо секрет напрямую из-за угрозы «человек-в-середине». Вместо этого вы можете подписывать трафик, используя свой секрет, и проверять целостность любых запросов, поступающих на ваш сервер. Один из стандартных способов сделать это - вычислить HMAC сообщения, заключенного в секрет. Я работаю в компании, у которой есть продукт безопасности, который также работает в этой области, поэтому меня интересуют такие вещи. Фактически, вот статья blog от одного из моих коллег, который использует большую часть этого.
Сколько я должен делать?
С любой безопасностью совет, как это, вы должны принять решение о затратах / выгодах о том, как сильно вы хотите сделать это для того, чтобы кто-то ворвался. Если вы являетесь банком, защищающим миллионы клиентов, ваш бюджет полностью отличается от того, кто поддерживает приложение в свое свободное время. Практически невозможно предотвратить, чтобы кто-то нарушил вашу безопасность, но на практике немногим людям нужны все колокола и свистки, и с некоторыми основными мерами предосторожности вы можете пройти долгий путь.
Ключ App-Secret должен оставаться закрытым - но при выпуске приложения они могут быть отменены некоторыми ребятами.
blockquote>для этих парней он не скрывает, блокирует либо код
ProGuard
. Это рефактор, и некоторые платные обфускаторы вставляют несколько побитовых операторов, чтобы вернуть строкуjk433g34hg3
. Вы можете сделать 5-15 минут дольше взлома, если вы работаете 3 дня:)Лучший способ сохранить это как есть, imho.
Даже если вы храните на стороне сервера (ваш ПК), ключ может быть взломан и распечатан. Может быть, это занимает больше всего времени? Во всяком случае, это всего лишь несколько минут или несколько часов в лучшем случае.
Обычный пользователь не декомпилирует ваш код.
Что бы вы ни делали, чтобы защитить секретные ключи, это не будет реальным решением. Если разработчик может декомпилировать приложение, нет способа защитить ключ, скрывая ключ, это просто защита от неизвестности, а также обфускация кода. Проблема с обеспечением секретного ключа заключается в том, что для его защиты вам нужно использовать другой ключ, и этот ключ также должен быть защищен. Подумайте о ключе, спрятанном в ящике, который заблокирован ключом. Вы помещаете коробку внутри комнаты и запираете комнату. У вас остается другой ключ для обеспечения безопасности. И этот ключ все еще будет жестко закодирован внутри вашего приложения.
Поэтому, если пользователь не вводит ПИН или фразу, нет способа скрыть ключ. Но для этого вам нужно будет иметь схему управления PIN-кодом, происходящим вне диапазона, а это означает, что с помощью другого канала. Конечно, это не практично для обеспечения ключей для таких сервисов, как API Google.