2

アプリケーションにのみアクセスできる必要がある個人情報を含むデータベースがあります。データベースファイルをassetsフォルダーに追加しました。このフォルダーは、アプリの最初の実行時にアプリケーションのデータベースディレクトリにコピーされますが、「assets」ディレクトリと「data」ディレクトリ(ルートデバイス上)は他のアプリケーションからアクセスできるため、暗号化することにしました。データベース。AndroidのデフォルトのSQLiteデータベースはデータの暗号化を提供しないため、Android用のSQLCipherhttp://sqlcipher.net/sqlcipher-for-android/を使用することにしまし

これでデータベースの暗号化に成功し、特定のパスワードを使用してデータベースにアクセスできます。しかし、問題は残っています...このパスワードはどこに保存すればよいですか?私のアプリケーションにのみアクセスできるようにします。

  1. 難読化されていても、逆コンパイルするとアクセスできるため、ハードコーディングできません。
  2. ファイルシステムにも保存できません(アセット/生)
  3. ユーザーはハッカーである可能性があるため、ユーザーに入力を求めることはできません

サーバーとのやり取りがまったくないスタンドアロンアプリです

4

2 に答える 2

5

Can't ask the user to enter it as the user could be a hackerそれでは、安全に保管する方法はありません。既に特定したのと同じ理由で、具体的にはコードを逆コンパイルできるため、アクセス可能なコードを保存する場所は逆コンパイルによって把握できるため、適切なアクセス権を持つコードによって取得できます。

ユーザーが提供するものは、ユーザーが保存する場所 (おそらくユーザーの頭の中) に保存されます。これはソフトウェアがアクセスできるものではないため、マルウェア攻撃のリスクを軽減するのに理想的です. 入力したパスワードが有効な場合、ユーザーが承認されているかどうかを知る方法はありませんが、キーの最小長、入力試行の最大回数 (遅延やその他のロックアウトを導入する前) などのポリシーを定義できます。 .

于 2012-08-14T20:40:02.180 に答える
2

この回答がどれほど正確かはわかりませんが、Androidオタクからの回答が欲しいので投稿しています

C コードは逆コンパイルが難しいことを考慮して、パスワードを生成するアルゴリズムを含む Android NDK を使用して単純なネイティブ C ライブラリ (.so) を作成しました。このアルゴリズムは、アプリが証明書によって署名されている場合にのみ実行されます。誰かが他のアプリでこのライブラリを再利用すると、証明書が一致しないため、パスワードが返されません。この投稿からこのアイデアを得ました: 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);
}
于 2012-08-17T01:30:30.407 に答える