2012-08-14 4 views
2

У меня есть база данных, содержащая личную информацию, которая должна быть доступна только моему приложению. Я добавил файл базы данных в папку с ресурсами, которая в первый раз копируется в каталог базы данных приложений, но в каталоге «assets» и «data» (на корневых устройствах) может быть доступ к любому другому приложению. Поэтому я решил зашифровать база данных. Android по умолчанию SQLite Database не обеспечивает шифрование данных, поэтому я решил использовать SQLCipher для android http://sqlcipher.net/sqlcipher-for-android/.Как защитить пароль (зашифрованный) на Android?

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

  1. Невозможно жестко записать его, поскольку он будет доступен после декомпиляции, даже если он запутан.
  2. не может хранить его в файловой системе либо (активы/сырье)
  3. Не может попросить пользователя ввести его как пользователь может быть хакером

Это автономное приложение без сервера взаимодействие вообще

+1

Если вы видите пользователя в качестве атакующего, вы не можете что-либо на стороне клиента доверять. Просто как тот. Вы можете просто бросать тонны обфускации в проблему, а затем надеяться, что никто не захочет ее сломать. – CodesInChaos

+0

Почему нет взаимодействия с сервером? Если у вас действительно нет веских оснований, вы должны использовать сервер для хранения ключа, на мой взгляд. – Entreco

ответ

5

Can't ask the user to enter it as the user could be a hacker Тогда у вас нет способа безопасно его хранить. По тем же причинам, которые вы уже определили, в частности, что ваш код можно декомпилировать, любое место, где вы храните его, которое доступно, может быть выяснено путем декомпиляции и, следовательно, получено любым кодом с правом доступа.

Что-то, что предоставляет пользователь, хранится везде, где пользователь хранит его - предположительно, в его голове. Это не то программное обеспечение, которое может получить доступ, что делает его идеальным для снижения риска атаки вредоносного ПО. Если введенный пароль действителен, вы не можете узнать, разрешен ли пользователь или нет, однако вы можете определить политику, такую ​​как минимальная длина ключа, максимальное количество попыток ввода (до введения некоторой задержки или другой блокировки) и т. Д. .

2

Я не уверен, насколько точны этот ответ, но все-таки размещать его, потому что я хочу некоторый ответ от Android вундеркиндов

Учитывая код C трудно декомпилировать, я написал простую родную библиотеку C (.so) с помощью Android NDK, который содержит алгоритм для генерации пароля. Этот алгоритм выполняется только в том случае, если приложение подписано моим сертификатом. Если кто-то повторно использует эту библиотеку в любом другом приложении, она не вернет пароль, поскольку сертификат не будет соответствовать. Я получил эту идею с этого поста: http://digital-identity.dk/2010/12/protecting-ip-in-android-applications/

Это, как я получить сертификат:

void Java_dk_digitalidetity_android_SomeClass_SomeMethod(JNIEnv* env, jobject obj) { 
    // this.getPackageManager() 
    jclass cls = (*env)->GetObjectClass(env, obj); 
    jmethodID mid = (*env)->GetMethodID(env, cls, "getPackageManager", "()Landroid/content/pm/PackageManager;"); 
    jobject packageManager = (*env)->CallObjectMethod(env, obj, mid); 

    // this.getPackageName() 
    mid = (*env)->GetMethodID(env, cls, "getPackageName", "()Ljava/lang/String;"); 
    jstring packageName = (jstring) (*env)->CallObjectMethod(env, obj, mid); 

    // packageManager->getPackageInfo(packageName, GET_SIGNATURES); 
    cls = (*env)->GetObjectClass(env, packageManager); 
    mid = (*env)->GetMethodID(env, cls, "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;"); 
    jint flags = GET_SIGNATURES; 
    jobject packageInfo = (*env)->CallObjectMethod(env, packageManager, mid, packageName, flags); 

    // packageInfo->signatures 
    cls = (*env)->GetObjectClass(env, packageInfo); 
    jfieldID fid = (*env)->GetFieldID(env, cls, "signatures", "[Landroid/content/pm/Signature;"); 
    jobject signatures = (*env)->GetObjectField(env, packageInfo, fid); 

// signatures[0] 
    jobject signature = (*env)->GetObjectArrayElement(env, signatures, 0); 

// signature->toByteArray() 
    cls = (*env)->GetObjectClass(env, signature); 
    mid = (*env)->GetMethodID(env, cls, "toByteArray", "()[B"); 
    jbytearray certificate = (*env)->CallObjectMethod(env, signature, mid); 
} 
+0

Код в общем объекте рассматривается некоторыми, чтобы его легче было атаковать, потому что отладчик позволяет вам сценарий легко пройтись по нему. Этому способствует возможность писать чистую программу на C, чтобы подключаться к вашему совместному коду и вызывать его, дизассемблировать и вносить изменения в код на лету. Как только правильные изменения будут идентифицированы, двоичный файл может быть взломан, и поскольку у Android нет подписи на изображениях эльфа, у атакующего (с правильными способностями) будет меньше препятствий для преодоления. Для взлома схемы требуется только один успешный злоумышленник. – mah

+0

C Общий объект имеет встроенную проверку внутри, которая соответствует сигнатуре приложения. Если кто-то еще звонит, он никогда не попадет в чувствительный код.Почему кто-то отлаживает этот код, который никогда не выполняется? – Saqib

+0

вы говорите о подписи вашего apk, я говорю о том, что собственное расширение libXXX.so не указано. Когда ваше приложение установлено, его собственная библиотека извлекается в файловую систему и никогда не упоминается внутри apk. Что касается проверки подписи apk, то - кто-то, кто может изменить .so, в равной степени может изменить его, чтобы отключить проверку подписи apk, и поскольку этот код, вероятно, проходит через интерфейс JNI обратно в виртуальную машину, его относительно легко найти. – mah

Смежные вопросы