指紋認証は、多くの Android デバイスに組み込まれているタッチセンサーを使用してユーザーを識別し、デバイスとアプリ内決済オプションなどのアプリケーション機能の両方にアクセスできるようにするためのものです。 指紋認証の実装は多段階のプロセスであるため、最初は圧倒されるように思えるかもしれません。 しかし、個々のステップに分解すると、そのプロセスははるかに複雑ではなくなります。 基本的な用語では、指紋認証は主に、キー、暗号化を実行する暗号、および認証プロセスを処理する指紋マネージャを含む暗号化の問題です。
この章では、指紋認証の概要と、実装への実用的なアプローチを示す詳細で段階的なチュートリアルの両方を提供します。
指紋認証の概要
Android アプリ内で指紋認証を実装するには基本的に 10 ステップがあります。 これらの手順をまとめると、次のようになります。 プロジェクトの Manifest ファイル内で指紋認証の許可を要求します。
2. アプリが実行されているデバイスのロック画面が PIN、パターンまたはパスワードで保護されていることを確認します (指紋は、ロック画面が保護されているデバイス上でのみ登録可能)。
3. 少なくとも 1 つの指紋がデバイスに登録されていることを確認します。 Keystoreインスタンスを使用して、Android Keystoreコンテナにアクセスします。 これは、Android端末の暗号鍵の安全な保管に使用されるストレージ領域です。 KeyGeneratorクラスを使用して暗号鍵を生成し、Keystoreコンテナに格納します。 手順 5 で生成した鍵を使用して Cipher クラスのインスタンスを初期化します。
8. Cipher インスタンスを使用して CryptoObject を作成し、手順 4 で作成した FingerprintManager インスタンスに代入します。 FingerprintManagerインスタンスのauthenticateメソッドを呼び出します。
10.FingerprintManagerインスタンスのauthenticateメソッドを呼び出します。 認証処理で発生するコールバックを処理するメソッドを実装します。 認証に成功したら、保護されたコンテンツまたは機能へのアクセスを提供します。
上記の各ステップは、この章の残りの部分で説明するチュートリアルを通じて、より詳細に説明します。
Creating the Fingerprint Authentication Project
この例を開始するには、Android Studio 環境を起動して新しいプロジェクトを作成し、Application name フィールドに FingerprintDemo、ebookfrenzy.NET を入力し、Fingerprint.NET と入力します。
Form factors 画面で Phone and Tablet オプションを有効にし、最小 SDK 設定を API 23: Android 6.0 (Marshmallow) に設定します。 FingerprintDemoActivity という名前の空のアクティビティと activity_fingerprint_demo という名前のレイアウトの作成を要求して、設定画面を続行します。
Configuring Device Fingerprint Authentication
指紋認証はタッチ センサーを含み、デバイスを保護し少なくとも 1 つの指紋を登録する適切な設定手順を踏んだデバイスでのみ利用可能です。 指紋認証をテストするためのエミュレーター セッションの構成手順については、「Android Studio 2 AVD Emulator の使用と構成」の章を参照してください。
物理デバイス上で指紋認証を構成するには、まず設定アプリケーションを開き、セキュリティ オプションを選択します。 セキュリティの設定画面で、[指紋]オプションを選択します。 表示された情報画面で[続行]ボタンをクリックし、指紋の設定画面に進みます。 指紋認証を有効にする前に、バックアップの画面ロック解除方法(PIN番号など)を設定する必要があります。 ロック画面がまだ保護されていない場合は、[Set Up Screen Lock] ボタンをクリックし、手順に従い、PIN、パターン、またはパスワードのいずれかのセキュリティを設定します。
ロック画面が保護されたら、指紋検出画面に進み、指示があったらセンサーに触れ(図62-1)、必要に応じて追加の指紋を追加するプロセスを繰り返し実行します。
図 62-1
マニフェスト ファイルに指紋権限を追加する
指紋認証には、アプリがプロジェクトのマニフェスト ファイル内に USE_FINGERPRINT 許可を要求することが必要です。 Android Studio のプロジェクト ツール ウィンドウで、アプリ -> manifests -> AndroidManifest.xml ファイルを検索して編集し、次のように権限要求を追加します。
Figure 62-2
このアイコンのコピーは、次の URL からダウンロードできます:
OS のファイル システム ナビゲーターを開き、新しくダウンロードした画像を選択して Ctrl-C (Mac OS X では Cmd-C) を押し、ファイルをコピーします。 Android Studioに戻り、app -> res -> drawableフォルダーを右クリックし、メニューオプションのPasteを選択して、画像ファイルのコピーをプロジェクトに追加します。 コピー] ダイアログが表示されたら、[OK] ボタンをクリックしてデフォルト設定を使用します。
Designing the User Interface
この例をできるだけシンプルにしておくために、ユーザー インターフェイス内の要素は TextView と ImageView のみとします。 Activity_fingerprint_demo.xml レイアウトリソースファイルを見つけて選択し、デザイナーツールにロードします。 読み込んだら、サンプルのTextViewオブジェクトを削除し、パネルからImageViewオブジェクトをドラッグ&ドロップして、レイアウトキャンバスの中央に配置します。
プロパティパネルで、src属性を見つけ、対応するテキストフィールドをクリックし、図62-3でハイライトされているボタンをクリックして、リソースダイアログを表示します:
図 62-3
ダイアログの左側のパネルで、Drawable オプションを選択します。 メインパネルで、図62 4に示すように検索ボックスに ic_fp を入力し、指紋アイコンを探します。
図 62-4
パレットから大きなテキストオブジェクトを見つけ、それが ImageView オブジェクトの下に配置されるようにドラッグ アンド ドロップします。 オブジェクトをダブルクリックし、テキストを「タッチセンサー」と表示されるように変更します。 電球のアイコンを使って、touch_sensorという名前のリソースに文字列を取り出します。
上記の手順を完了すると、レイアウトは図62-5に示すようになります。
図 62-5
キーガードと指紋マネージャサービスにアクセスする
指紋認証では、KeyguardManager と FingerprintManager という2種類のシステム サービスを使っています。 FingerprintDemoActivity.java ファイルにある onCreate メソッドを編集して、これらの 2 つのサービスへの参照を次のように取得します。 しかし、指紋認証を試みる前に、これらの要件が満たされていることを確認するために、アプリに防御的なコードを含めることが重要です。 これらの手順は、FingerprintDemoActivity.java ファイルにある onCreate メソッド内で、Keyguard および Fingerprint manager サービスを利用して実行されます。 USE_FINGERPRINT 権限がアプリに構成されていることを確認するコードも追加されたことに注意してください。
上記のコード変更では、まず Keyguard Manager を使用して、画面のロック解除方法のバックアップが構成されていることを確認します (つまり、画面のロック解除に指紋認証の代わりとして PIN またはその他の認証方法を使用できることです)。 ロック画面が保護されていない場合、コードはユーザーに問題を報告し、メソッドから戻ります。
次に、指紋マネージャを使用して、少なくとも1つの指紋がデバイスに登録されていることを確認し、再度問題を報告し、必要に応じてメソッドから離れます。
Accessing the Android Keystore and KeyGenerator
指紋認証プロセスの一部には、Android Keystore システムを使用してデバイスに安全に格納される暗号化キーの生成が含まれます。 キーを生成して保存する前に、アプリはまずキーストアへのアクセスを取得する必要があります。 FingerprintDemoActivity.java ファイルに generateKey という名前の新しいメソッドを実装し、鍵の生成と保存のタスクを実行するようにします。 最初は、Keystore にアクセスするコードのみを次のように追加します。
Keystore クラスの getInstance メソッドを呼び出し、Android 標準 keystore コンテナーの識別子(「AndroidKeyStore」)を渡すことによって、Keystore への参照を取得します。 チュートリアルの次のステップは、KeyGenerator サービスを使用して鍵を生成することです。 この鍵を生成する前に、KeyGenerator のインスタンスへの参照を取得するコードを追加する必要があり、生成する鍵の種類と、鍵を保存する Keystore コンテナーの名前を引数として渡します:
Generating the Key
ここで、Android Keystore コンテナーと KeyGenerator インスタンスを参照していることから、次のステップは暗号化処理に使用する鍵を生成することです。 FingerprintDemoActivity.java ファイル内に残って、次のように新しいコードを追加します。
上記の変更については、少し説明が必要です。 多くの追加モジュールをインポートした後、コードは、キーをキーストア コンテナーに格納するときに使用される名前 (この場合は「example_key」) を表す文字列変数を宣言します。
次に、キーストア コンテナーがロードされ、KeyGenerator が初期化されます。 この初期化処理では、生成される鍵の種類を指定するために KeyGenParameterSpec.Builder クラスを利用する。 これには、鍵の名前の参照、暗号化と復号化の両方に使用できるような鍵の構成、さまざまな暗号化パラメータの設定などが含まれます。 setUserAuthenticationRequired メソッドを呼び出すと、ユーザーが鍵を使用するたびに指紋認証が必要になるように鍵を設定できます。
Initializing the Cipher
キーが生成されたので、次のステップは暗号化された FingerprintManager.CryptoObject インスタンスを作成するために使用する暗号を初期化することです。 この CryptoObject は順に、指紋認証プロセスで使用されます。 Cipher の構成では、Cipher インスタンスを取得し、Keystore コンテナに格納されているキーで初期化します。
Cipher クラスの getInstance メソッドを呼び出して Cipher インスタンスを取得し、その後フィンガープリント認証に必要なプロパティで設定します。 次に、以前に生成された鍵が Keystore コンテナから抽出され、Cipher インスタンスを初期化するために使用されます。 エラーは適宜処理され、Cipher 初期化プロセスの成功または失敗に基づいて真または偽の結果が返されます。
generateKey および cipherInit メソッドの両方について作業が完了しました。 次のステップでは、これらのメソッドを呼び出すように onCreate メソッドを変更し、暗号の初期化に成功した場合は CryptoObject インスタンスを作成します。
CryptoObject インスタンスの作成
残りの FingerprintDemoActivity.NET Framework 内で、CryptoObject インスタンスを作成します。
プロジェクトの最後のタスクは、実際の指紋認証を処理する新しいクラスの実装です。
指紋認証ハンドラクラスの実装
この章のこれまでの作業のほとんどは、キー、暗号、暗号オブジェクトの面で指紋認証の準備に関わってきました。 実際の認証は、FingerprintManager インスタンスの authenticate メソッドの呼び出しにより開始されます。 ただし、このメソッド呼び出しは、認証の成功または失敗に応じて、多数のコールバックイベントのうちの 1 つをトリガーします。 authenticate メソッドコールとコールバックハンドラメソッドの両方を FingerprintManager.AuthenticationCallback クラスを継承したクラスで実装する必要があります。
Android Studio のプロジェクト ツール ウィンドウ内の app -> java -> com.ebookfrenzy.fingerprintdemo のエントリに移動し、その上で右クリックします。 表示されたメニューから、「New -> Java Class」オプションを選択し、「Create New Class」ダイアログを表示します。 クラス名を FingerprintHandler とし、[OK]ボタンをクリックしてクラスを作成します。
新しいクラスファイルを編集し、FingerprintManager.FingerprintHandler を拡張します。AuthenticationCallback を拡張し、いくつかの追加モジュールをインポートし、クラスのインスタンスが作成されるときにアプリケーション コンテキストが渡されるようにするコンストラクター メソッドを実装します (コンテキストは、認証の状態をユーザーに通知するコールバック メソッドで使用されます)。 呼び出されたとき、このメソッドは FingerprintManager および CryptoObject インスタンスを渡される必要があります。 このメソッドを startAuth と名付け、FingerprintHandler.FM に実装します。次に、コールバック ハンドラ メソッドを追加します。各メソッドは、指紋認証の結果を示すトースト メッセージを表示するように実装されています。 FingerprintDemoActivity.java ファイルを編集し、onCreate メソッドの末尾を以下のように修正します。
プロジェクトのテスト
プロジェクトが完了したら、物理的な Android 機器またはエミュレーター セッションでアプリを実行します。 実行したら、指紋センサーをタッチするか、エミュレーター内の拡張コントロール パネルを使用して、「Android Studio 2 AVD Emulator の使用と設定」の章で説明したように指紋のタッチをシミュレートしてください。 登録された指紋が検出されると、図 62-6 に示すように、認証の成功を示すトースト メッセージが表示されます。 今回は、認証に失敗したことを示すトースト メッセージが表示されるはずです。
Summary
Android 内の指紋認証は、最初は複雑に見えるかもしれない複数のステップからなるプロセスです。 しかし、個々のステップに分解すると、プロセスが明確になります。 指紋認証には、キー、暗号、およびキーストレージの使用と、FingerprintManager クラスの機能の組み合わせが含まれます。 この章では、これらのステップの紹介と、Android内での指紋認証の実用的な実装を示すことを目的としたサンプルアプリケーションプロジェクトの作成を通じて作業を行ってきました。