ユーザーが操作を実行するためにサインインする必要がある Android アプリを開発しています。しかし、ほとんどの Android ハンドセットでは、人々は「サインインしたままにする」を使用します。その場合、アプリ内でユーザー名とパスワードの値を維持する必要があります。SharedPreferences
または SQLite データベースを使用する必要がありますか、それとも他に使用できるものがありますか。
どうすれば安全にできますか?
10 に答える
はい、これは Android ではトリッキーです。ルート化されたデバイスを持っている人は基本的に自分のパスワードを世界中に表示するため、プレーンテキストのパスワードを設定に保存したくありません。反対に、暗号化されたパスワードを使用することはできません。これは、暗号化/復号化キーをデバイスのどこかに保存する必要があり、これもルート攻撃の影響を受けやすいためです.
しばらく前に使用した1つの解決策は、サーバーに「チケット」を生成させ、それをデバイスに戻すことです。これは、一定期間有効です。このチケットは、すべての通信でデバイスによって使用されます。もちろん SSL を使用するため、チケットを盗むことはできません。このようにして、ユーザーはサーバーでパスワードを一度認証し、サーバーは期限切れのチケットを送り返し、パスワードはデバイスのどこにも保存されません。
OpenID、Facebook、さらには Google API など、いくつかの 3 つの認証メカニズムがこのメカニズムを使用しています。欠点は、チケットの有効期限が切れるたびに、ユーザーが再ログインする必要があることです。
最終的には、アプリケーションをどの程度安全にしたいかによって異なります。これが単にユーザーを区別するためであり、銀行口座や血液型などの極秘情報が保存されていない場合は、PWD を平文でデバイスに保存するだけで十分です :)
頑張ってください、あなたが決定した方法があなたの特定の状況に最適です!
編集:この手法は、セキュリティの責任をサーバーに移すことに注意してください。サーバーでのパスワード比較には、塩漬けハッシュを使用する必要があります。これは、この質問の他のコメントのいくつかに見られるアイデアです。これにより、デバイスの EditText ビュー、サーバーへの SSL 通信、サーバーの RAM 以外の場所に平文のパスワードが表示されるのを防ぎ、パスワードをソルトしてハッシュします。ディスクに保存されることはありません。これは Good Thing™ です。
他の人が言っているように、Android にパスワードを保存してデータを完全に保護する安全な方法はありません。パスワードのハッシュ化/暗号化は素晴らしいアイデアですが、「クラッカー」の速度が低下するだけです。
そうは言っても、これは私がしたことです:
1)シードとテキストを取り、それを暗号化するこのsimplecryto.java
クラスを使用しました。2)SharedPreferences
ルート化されていないデバイスに保存されたファイルを保護するプライベート モードで使用しました。3) 私が simplecryto に使用したシードはバイト配列で、文字列よりも逆コンパイラで見つけるのが少し難しいです。
私のアプリケーションは最近、私の会社が雇った「ホワイト ハット」セキュリティ グループによってレビューされました。彼らはこの問題にフラグを立て、OAUTH を使用する必要があることを示しましたが、それを LOW リスクの問題としてリストしました。
「クラッカー」は、デバイスに物理的にアクセスし、ルート化し、シードを見つけるのに十分な注意を払う必要があることに注意してください。
セキュリティが本当に気になるなら、「ログイン状態を維持する」オプションはありません。
セキュリティを危険にさらすことなくこれを行う最も安全な方法は、共有設定を使用して、最後にログインした人のユーザー名のみを保存することです。
また、ユーザーのテーブルに、数値のブール値 (1 または 0) を保持する列を導入して、その人が "remember me" チェックボックスをオンにしたかどうかを表します。
アプリを起動するときに、getSharedPreferences()
関数を使用してユーザー名を取得し、それを使用してホストされているデータベースにクエリを実行して、signedin 列が 1 または 0 のどちらであるかを確認します。1 は、ユーザーが [remember me] チェックボックスをオンにしたことを示します。
//encode password
pass_word_et = (EditText) v.findViewById(R.id.password_et);
String pwd = pass_word_et.getText().toString();
byte[] data = new byte[0];
try {
data = pwd.getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String base64 = Base64.encodeToString(data, Base64.DEFAULT);
hbha_pref_helper.saveStringValue("pass_word", base64);
//decode password
String base64=hbha_pref_helper.getStringValue("pass_word");
byte[] data = Base64.decode(base64, Base64.DEFAULT);
String decrypt_pwd="";
try {
decrypt_pwd = new String(data, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}