スマートフォンはますます高速化し、高機能になっています。そして、私たちの記憶力を補ったり、世界とつながり、友人や家族やその先のコミュニティと連絡を取り合うための主なインターフェースになり、私たちの暮らしの中で重要な役割を果たしています。この進化に合わせて、私たちが最も個人的な情報をスマートフォンに保存し、管理するようになったことも自然な流れです。そして私たちは、さまざまな形でスマートフォンをデジタルな自分や実際の自分の拡張として扱うようになっています。

スマートフォンに個人情報を預ける、その信頼を得て守ることこそ Android セキュリティ チームの最優先事項です。チームは Android デバイスがユーザーデータのプライバシーや機密性を尊重することを重視しています。その作業の土台となるのが、いわばデバイスの正面玄関となるロック画面です。つまり、ロック画面はデバイスを所有している特定のユーザーだけが個人データにアクセスできることを保証します。

このブログ記事では、Android デバイスのロック画面操作に関する最近の改善点について説明します。さらに、もう少し一般的な認証についても触れたいと思います。とりわけ、生体認証と環境という 2 種類の認証方式について重点的に取り上げます。この 2 つは潜在的に大きな可能性を秘めていると同時に、適切に設計されなければ重大なリスクにもなり得ます。

階層化認証モデル

ロック画面と認証の改善点について詳しく説明する前に、いくつかの背景情報をお伝えします。この情報は、今回の改善点における相互の関連性を把握するために役立ちます。今回の変更は、階層化認証モデルのフレームワークに当てはめてみるとイメージしやすいはずです。階層化認証モデルとは、Android に搭載されているすべての認証方式を概念的に分類し、相互の関連性や、この分類に基づく制約をまとめたものです。

このモデル自体はかなりシンプルで、認証方式を 3 つに分類しています。階層が上がるほどセキュリティのレベルは下がり、それに比例して制約が増えます。第 1 階層では、ユーザーが機能を利用するために第 1 の認証方式の再入力を求められるのは、特定の状況下(たとえば、起動ごとや 72 時間ごとなど)のみであるため、制約は最も少ないと言えます。第 2 階層と第 3 階層の制約はさらに強くなります。最初に第 1 の認証方式が登録されていないと設定および利用できないうえに、機能を制限するさらに強い制約が存在するためです。

  1. 第 1 階層 - 知識ファクタ:
    最初の階層は、知識ファクタ、すなわちユーザーが知っていることを利用する方式です。たとえば、PIN(暗証番号) やパターン、パスワードなどです。推測しにくい複雑なパスワードなど、エントロピーの高い優れた知識ファクタは、最高レベルの身元保証を提供できる可能性があります。

    Android では、デバイスがハードウェア機能と指数バックオフによって総当たり攻撃に対する保護を提供しているため、知識ファクタは特に有用です。つまり、Android デバイスでは、5 回失敗するたびにハードウェア機能によるタイムアウトが適用されるため、攻撃者が PIN やパターン、パスワードを繰り返し予測することはできません。知識ファクタを利用するすべてのユーザーには、ファイルベースの暗号化(File Based Encryption、FBE)や暗号化デバイス バックアップなどを使用できるという追加のメリットもあります。

  2. 第 2 階層 - 生体認証: 第 2 階層は主に生体認証で構成されます。これは、 ユーザー自身で認証する方式です。第 2 の認証方式の例として、顔や指紋による認証があげられます。生体認証は利便性が高くなりますが、デバイスでユーザーの身元を確認する方法としてのセキュリティは低くなる可能性があります。Android の生体認証については、次のセクションで詳しく取り上げます。

  3. 第 3 階層 - 環境: 最後の階層は、 ユーザーの所有物を利用する方式です。その 1 つが物理トークンです。たとえば、Smart Lock の信頼できるデバイスを使う場合、許可リストに登録された Bluetooth デバイスとペアリングしてスマートフォンをロック解除します。また、デバイス周辺の物理環境に固有のものを使うこともできます。たとえば、Smart Lock の信頼できる場所では、スマートフォンを許可リストに登録された場所に運ぶことでロックを解除できます。

第 3 の認証の改善

信頼できる場所や信頼できるデバイス(そして一般的な第 3 の方式)を使うと、便利な方法でデバイスの内容にアクセスできます。しかし、これらに共通する根本的な問題は、最終的にユーザーの身元確認機能の精度の低さに集約されます。たとえば、信頼できる場所を使っているスマートフォンのロックは、ユーザーの自宅のそばを通り過ぎるだけで解除できるかもしれません。また、既製のソフトウェア無線と多少のスクリプトを使えば、比較的簡単に GPS シグナルを偽装することもできます。信頼できるデバイスも同様で、許可リストに登録された Bluetooth デバイスにアクセスできれば、ユーザーのスマートフォン内のすべてのデータにアクセスできることになります。

そこで、Android 10 の環境階層に大幅な改善が加えられ、第 3 階層は積極的にロックを解除する仕組みからロック解除を延長する仕組みに変わっています。この新しいモードでは、第 3 階層でデバイスのロックを解除できなくなりました。その代わり、最初に第 1 の方式か第 2 の方式を使ってデバイスのロックを解除している場合、最大 4 時間にわたってロック解除状態を継続します。

Android の生体認証の詳細

生体認証の実装には、幅広いセキュリティ特性があります。そこで、次にあげる 2 つの重要な要素を利用して特定の実装のセキュリティを判定しています。

  1. 構造上のセキュリティ: カーネルやプラットフォームの侵害に対する生体認証パイプラインの耐性を表します。カーネルやプラットフォームが侵害され、未加工の生体認証データが読み取られたり、パイプラインに合成データを注入されたりしても認証結果に影響が及ぶことがない場合、パイプラインは安全であると見なされます。

  2. なりすましの可能性: なりすまし受け入れ率(Spoof Acceptance Rate、SAR)で測定します。SAR は Android P で初めて導入された指標で、なりすましに特化した攻撃に対する生体認証の耐性を測定することを目的としています。SAR の詳細や測定方法については、生体認証を用いたロック解除のセキュリティ測定をご覧ください。
この 2 つの要素を使い、セキュリティの高い順に並んだ 3 つのクラスのいずれかに生体認証を分類します。
  • クラス 3(以前の「å¼·」)
  • クラス 2(以前の「å¼±」)
  • クラス 1(以前の「便利」)

各クラスには、一連の制約が紐付いています。この制約は、それぞれの使いやすさとセキュリティのレベルのバランスをとることを目指したものです。

制約は、生体認証が第 1 階層の認証にフォールバックするまでの時間と、許可されているアプリ統合で表されています。たとえば、クラス 3 の生体認証はタイムアウトまでの時間が最も長く、すべてのアプリ統合オプションを利用できます。一方、クラス 1 の生体認証はタイムアウトまでの時間が最も短く、アプリ統合オプションは提供されません。概要を下の表に示します。完全版を確認したい方は Android Compatibility Definition Document(CDD)をご覧ください。

1 App Integration(アプリ統合)とは、API をアプリに公開すること(例: BiometricPrompt/BiometricManager、androidx.biometric、FIDO2 API などの統合によって)を意味します。

2 Keystore Ingegration(キーストア統合)とは、キーストアを組み込むこと(例: アプリの認証バインドキーをリリースするなど)を意味します。

メリットと注意点

生体認証を利用すると、高レベルのセキュリティを維持しつつ、ユーザーに利便性を提供できます。ユーザーは生体認証を利用するために第 1 の認証方式を設定する必要があるので、ロック画面の採用が促進されます(生体認証を提供しているデバイスは、そうでないデバイスに比べてロック画面の採用が平均 20% 高くなっています)。これにより、ロック画面が提供するセキュリティ機能のメリットを活用できるユーザーが増えます。具体的には、ユーザーの機密データへの認証されていないアクセスを防ぐことができ、暗号化バックアップなどの第 1 の認証方式によるその他のメリットも受けることができます。さらに、生体認証は、肩越しにのぞき見るショルダー サーフィン攻撃によって PIN やパターン、パスワードを入力するのを見た攻撃者が認証情報を再現しようとする試みを減らすうえでも役立ちます。

ただし、生体認証を使うことによるトレードオフ(発生し得るリスク)をユーザーが理解することが重要です。特に大切なのは、完璧な生体認証システムはないということです。これは Android だけでなく、すべてのオペレーティング システム、フォームファクタ、テクノロジーに対して言えることです。たとえば顔を使った生体認証の実装なら、ユーザーに似た家族やユーザーの 3D マスクでロックが解除できてしまうかもしれません。指紋を使った生体認証の実装なら、ユーザーの潜在指紋を使ってなりすませるかもしれません。このようななりすまし攻撃を緩和するため、なりすまし対策や Presentation Attack Detection(PAD)テクノロジーの開発が進められていますが、これらは緩和策であり、予防策ではありません。

生体認証の利用による潜在的なリスクを緩和するための Android の取り組みとして、Android P で導入されたロックダウン モードがあります。必要な場合、Android ユーザーはこの機能を使って一時的に生体認証や Smart Lock(信頼できる場所や信頼できるデバイスなど)、ロック画面の通知を無効化できます。

ロックダウン モードを使うには、まず第 1 の認証方式を設定し、その後に設定でロックダウン モードを有効化する必要があります。ロックダウン モードを有効化するための厳密な設定はデバイスのモデルによって異なりますが、Google Pixel 4 デバイスでは [Settings] > [Display] > [Lock screen] > [Show lockdown option] にあります。これを有効化すると、ユーザーは電源ボタンを押して電源ボタン メニューのロックダウン アイコンをクリックすることで、ロックダウン モードを起動できます。ロックダウン モードのデバイスは、第 1 の認証方式(PIN、パターン、パスワードなど)を使ってデバイスのロックを解除すると、ロックダウン解除状態に戻ります。

BiometricPrompt - 新 API

Android の生体認証が提供するセキュリティ保証のメリットを活用してもらい、生体認証をアプリに簡単に統合してユーザーの機密データの保護を強化できるようにするため、Android P で BiometricPrompt API を導入しました。

BiometricPrompt API を使用すると、さまざまなメリットが得られます。最も重要なことは、この API を使うと、アプリのデベロッパーが方式を意識せずに、さまざまな Android デバイスで生体認証を利用できることです(つまり、BiometricPrompt は、デバイスでサポートされているさまざまな生体認証方式の単一統合ポイントとして利用できます)。一方で、認証が提供する必要があるセキュリティ保証(フォールバックとしてのデバイス認証情報と合わせてクラス 3 またはクラス 2 の生体認証を必須とするなど)を制御することもできます。これにより、(ロック画面の他に)防御の第 2 階層でアプリデータを保護できることに加え、ユーザーの機密データを尊重することにもつながります。さらに、さまざまな Android デバイスのさまざまな方式の生体認証で一貫したユーザー エクスペリエンスを提供するため、BiometricPrompt は永続的な UI を提供しています。一部の情報(タイトルや説明など)をカスタマイズするオプションも存在します。

次のアーキテクチャ図に示すように、フレームワーク API やサポート ライブラリ(下位互換性を確保するための androidx.bitmetric)のどちらかを通して、Android デバイスのアプリに生体認証を組み込むことができます。注意すべき点は、FingerprintManager ãŒéžæŽ¨å¥¨ã«ãªã£ã¦ã„ることです。デベロッパーには、方式を意識しない認証としてBiometricPrompt ã«ç§»è¡Œã™ã‚‹ã“とが推奨されています。

BiometricPrompt の改善点

Android 10 では、BiometricManager クラスが導入され、デベロッパーはこれを使って生体認証の利用可否を照会できます。また、BiometricPrompt å‘けに指紋認証や顔認証が統合されています。

Android 11 では、BiometricManager.Authenticators インターフェースなどの新機能が導入されています。これを使うと、デベロッパーはアプリで受け入れる認証タイプを指定したり、BiometricPrompt ã‚¯ãƒ©ã‚¹ã§åˆ©ç”¨ã”との認証キーをサポートしたりできます。

詳しくは、Android 11 プレビューと Android 生体認証システムのドキュメントをご覧ください。BiometricPrompt API の詳しい使用方法については、ブログ記事 Using BiometricPrompt with CryptoObject: how and why や、Codelab Login with Biometrics on Android をご覧ください。



Reviewed by Yuichi Araki - Developer Relations Team and Hidenori Fujii - Google Play Developer Marketing, APAC


APK 内にパッケージされたデータ、またはサーバーからダウンロードしたデータのいずれかを、データベースに事前に取り込む必要があるとします。SQLite と Room のどちらでこの作業を行う場合でも、データベースを開く、スキーマを検証する、データベース ファイルをロックしてスレッドの同期を処理する、すべてのコンテンツをコピーする、データベースを閉じる、といった複数の処理を行う必要があります。

Room 2.2(現在ベータ版)より、あらかじめパッケージ化されたデータベースの場所に応じて、RoomDatabase.Builder#createFromAsset() または createFromFile() という 1 つのメソッドを呼び出すことで、データベースに事前にデータを取り込むことができます。本稿では、こうしたメソッドの使用方法、あらかじめパッケージ化されたデータを扱う際のヒント、およびマイグレーションが含まれる場合に何が起こるかについて説明します。

createFromAsset()

あらかじめパッケージ化されたデータベースがアプリの assets/ フォルダに含まれている場合は、createFromAsset() を使用し、アセットのパスをパラメータとして指定します。たとえば、データベースが assets/database/myapp.db にある場合は、“database/myapp.db” と指定します。

Room.databaseBuilder(appContext, TestDatabase.class, “Sample.db”)
   .createFromAsset(“database/myapp.db”)
   .build()

createFromFile()

データベースが assets/ フォルダに含まれていない場合、つまりサーバーからデータベースをダウンロードしてディスクに保存する場合は、createFromFile() を使用して File を指定します。

Room.databaseBuilder(appContext, TestDatabase.class, “Sample.db”)
   .createFromFile(File(“mypath”))
   .build()
🚫 インメモリ データベースでは、createFromAsset または createFromFile によるデータベースへのデータの事前取り込みをサポートしていません。この処理を行おうとすると RoomDatabase.build() メソッドは IllegalArgumentException をスローします。

ファイルのアクセス権

Room は指定されたデータベースを開くのではなく、コピーします。そのため、File を使用する場合は、Room でファイルをコピーできるよう、読み取り権限があることを確認してください。

データベースの検証

Room では、データベースを別のバージョンにマイグレーションする際にデータベースの妥当性を保証します。そのために、アセットとファイルのどちらからデータベースを作成する場合も、同じ検証チェックを適用します。同様に、Room はデータのコピー元とコピー先のデータベースのスキーマが一致することを保証します。
💡 Room では、@Database アノテーションの exportSchema パラメータを使ってデータベース スキーマの書き出しが可能となっています。そのため、あらかじめパッケージ化されたデータベースを作成する際は、そこに定義されているスキーマを使用します。

マイグレーション

一般に、データベースのスキーマが変わる際、デベロッパーは@RoomDatabase アノテーション内のデータベースのバージョンを増分し、マイグレーションの実装または破壊的なマイグレーションの有効化のいずれかを行います。Room は、デバイスにすでにインストールされているバージョンと、アプリに定義されている最新バージョンを調べます。

たとえば、デバイス上のデータベースのバージョンが 2 で、@RoomDatabase に定義されているアプリのデータベース のバージョンが 4 であるとします。以下では、そのバージョンの組み合わせに対して、あらかじめパッケージ化されたデータベースがさらに追加された場合に、それぞれのシナリオで何が起きるかを説明します。

1. 破壊的なマイグレーションが有効になっていて、あらかじめパッケージ化されたデータベースのバージョンがアプリに定義されているバージョンよりも古い場合、データベースは削除され、データはコピーされません。

例: あらかじめパッケージ化されたデータベースのバージョンが 3 で、破壊的なマイグレーションが有効になっている場合、データベースは削除され、データはコピーされません。

2. 破壊的なマイグレーションが有効になっていて、あらかじめパッケージ化されたデータベースのバージョンがアプリに定義されているものと同じバージョンである場合、データベースは削除され、あらかじめパッケージ化されたデータベースからデータがコピーされます。

例: あらかじめパッケージ化されたデータベースのバージョンが 4(アプリのデータベースのバージョンと同じ)で、破壊的なマイグレーションが有効になっている場合、データベースは削除され、あらかじめパッケージ化されたデータベースからデータがコピーされます。

3. マイグレーションが実装されていて、@RoomDatabase アノテーションに指定されているバージョンよりもあらかじめパッケージ化されたデータベースのバージョンのほうが古い場合、Room はデータをコピーしてマイグレーションを実行します。

例: あらかじめパッケージ化されたデータベースのバージョンが 3 であり、バージョン 2 から 3 へのマイグレーションとバージョン 3 から 4 へのマイグレーションが実装されている場合、まずバージョン 2 から 3 へのマイグレーションが実行され、データベースがコピーされた後、バージョン 3 から 4 へのマイグレーションが実行されます。(ソースはこちら

On device db version, @RoomDatabase version, Pre-packaged db version, Migrations, Data copied
2, 4, 3, destructive, No
2, 4, 4, destructive, Yes
2, 4, 3, implemented, Yes and migrations run
💡あらかじめパッケージ化データベースのバージョンと、@RoomDatabase アノテーションで宣言されている最新のバージョンを同じにすることをおすすめします。そうすることで、マイグレーションのケースに対処する必要がなくなります。
📖 Room でのマイグレーションについて詳しくはこちらのブログ投稿を、マイグレーションのテストについてはこちらをご覧ください。
Room データベースに対して、アプリに含まれているデータから、またはファイルから、簡単にデータを取り込めるようになりました。Room ではデータの整合性を保護するとともに、必要に応じてデベロッパーによるマイグレーションの実施を支援します。

Posted by Yuichi Araki - Developer Relations Team


Google Play 開発者サービスと Firebase SDK を、今年中に Android Support Library から androidx-packaged ライブラリのアーティファクトに移行することになりました。目標としては、2019 å¹´ 6 月~7 月を予定しています。この変更により、SDK だけでなく最新の Jetpack コンポーネントもアプリ内で利用しやすくなります。

アプリが com.google.android.gms ライブラリや com.google.firebase ライブラリに依存している場合は、今回の移行に伴いご対応が必要となります。androidx-packaged ライブラリのアーティファクトでビルドしたアプリを簡易的にテストするには、gradle.properties ファイルに次の 2 行を追加します。

android.useAndroidX=true

android.enableJetifier=true

このビルドが問題なく機能すれば、それ以上の対応は必要ありません。新しい Google Play 開発者サービスと Firebase SDK をリリースと同時に利用できます。新しいビルドで問題が発生した場合や、この移行について詳しい情報が必要な場合は、公式の Jetpack 移行ガイドをご覧ください。androidx への移行が完了しましたら、改めてお知らせいたします。

Posted by Yuichi Araki - Developer Relations Team



ソースのリファクタリングにより、Java コード、XML リソース、Gradle 設定がアップデートされ、リファクタリングされたクラスと Maven アーティファクトを参照するようになります。この機能は、Android P を対象とするアプリ向けの Android Studio Canary 14 で利用できます。

古い Support Library を参照するライブラリに依存している場合、Android Studio を使用すると、依存関係の変換を介して、ライブラリが androidx を参照するようにアップデートすることができます。依存関係の変換は、Android Gradle プラグイン 3.2.0-alpha14 によって自動的に適用されます。このプラグインにより、androidx にパッケージ化された新しいクラスとアーティファクトを参照するように JAR と AAR の依存関係(および、推移的な依存関係)のバイトコードとリソースが書き換えられます。また、スタンドアロンの変換ツールを JAR 形式で提供する予定です。

次のステップ

AndroidX の導入は、既存のプロジェクトとコードベースに対する大きな変更であることを理解しています。Google の目的は、持続可能な成長、より高いモジュール性、より小さなコードサイズの実現に向けて Android ライブラリ プロジェクトをセットアップするための強固な基盤を提供することです。

これらの変更により、デベロッパーの皆さんが簡単に機能を見つけて、高品質のアプリをより短時間で実装できるようになることを願っていますが、移行には時間がかかり、すべてのデベロッパーの作成スケジュールに適合しない場合があることも理解しています。そのため、P Preview SDK の期間中は、android.support にパッケージ化されたライブラリ セットへのアップデートを引き続き並行して提供します。これらのアップデートでは、2018 å¹´ 3 月にリリースされた 28.0.0-alpha1 以降の 28.0.0 バージョニング スキームが継続されるとともに、android.support パッケージに依存している既存のプロジェクトとのソース互換性が引き続き確保されます。

28.0.0 の安定版リリースは、android.support としてパッケージされた最終版の機能リリースになる予定です。以降のすべての機能リリースは、androidx にパッケージ化されたアーティファクトとしてのみ利用可能になります。

このすばらしい未来に向けた取り組みを繰り返す中で、皆さんからご意見をお待ちしております。以下にコメントを入力して、フィードバックをお寄せください。また、AOSP で遭遇したバグについてもお知らせください

Android ライブラリの新時代を楽しみにしています。


Reviewed by Yuichi Araki - Developer Relations Team