SlideShare a Scribd company logo
アプリの鍵が消える時
DroidKaigi2018
2018/2/8
Akihiro Shiota
自己紹介
塩田 明弘(@aki_sh_7):発表者
 株式会社NTTデータ セキュリティ技術部 所属
 2014/4より社内のAndroidアプリ開発者向け
のセキュリティガイド作成やサポートに従事
金井 文宏:共同発表者
 NTTセキュアプラットフォーム研究所 所属
 2015/4よりAndroidアプリのセキュリティに
関する研究開発に従事
注意事項
本セッションの内容は所属会社の
見解を表すものではありません。
調査結果は2018/1/31時点のもの
となります。調査対象となってい
ない将来のバージョンでは動作が
異なる可能性があります。
目次
1. Android Keystore Providerとは
2. アプリの鍵が消える時
3. 消えることを見越して
4. まとめ
1.
Android Keystore Providerとは
鍵の管理って大変
どうしてもデータを端末に保存し
ないといけない時、ありますよね
 個人情報
 アクセストークン
 流用されたくない資産
保存するなら安全に保存したい
鍵の管理って大変
どうしてもデータを端末に保存し
ないといけない時、ありますよね
 個人情報
 アクセストークン
 流用されたくない資産
保存するなら安全に保存したい
→暗号化
鍵の管理って大変
どうしてもデータを端末に保存し
ないといけない時、ありますよね
 個人情報
 アクセストークン
 流用されたくない資産
保存するなら安全に保存したい
→暗号化
でも、鍵の管理が大変
Android Keystore プロバイダ
アプリ固有の鍵を生成できる機能
Android4.3から導入
Android6.0で、APIリニューアル
同時に共通鍵暗号もサポート
(6.0未満では、公開鍵暗号のみ)
Keystore プロバイダの歴史
OS version
4.0
(API lv15)
•KeyChain APIの導入
•端末へ独自の秘密鍵/証明書をインストール可能に
4.1
(API lv16)
•AOSPに keymaster関連のコードが出現
•この時点でもリフレクション等でUndocumentedな
APIを叩く事で一部のAndroid KeyStoreの機能を利
用可能
4.3
(API Lv18)
•(Publicな) Android KeyStore API 公開
• 公開鍵暗号(RSA)のみ、鍵長固定
Keystore プロバイダの歴史
OS version
6.0
(API Lv23)
•鍵生成時に鍵長、用途、暗号利用モード等細かいパラ
メータを設定可能に
•鍵の利用前にユーザ認証する機能が追加
•共通鍵暗号のサポート(AES, EC, HMAC, etc)
•Key Blobsに暗号化された鍵の他、認証に必要な属性
情報(タグ)が含まれるようになった
•keymaster HAL InterfaceのVerが0.3 -> 1.0へ
7.0
(API Lv24)
•Key Attestation機能の追加
•HW-Backedな端末で生成された鍵であるか、を検
証する機能
•keymaster HAL InterfaceのVerが1.0 -> 2.0へ
Keystore プロバイダの歴史
OS version
7.1
(API Lv25)
•version binding機能の追加
•鍵はOS&パッチのバージョンと紐付られるようにな
り、(脆弱性の見つかった)古いバージョンにロール
バックして鍵を抽出する事が不可能に
8.0
(API Lv26)
•Key Attestation機能の強化(ID attestation)
•特定の端末ID(e.g. IMEI) 環境下で生成された鍵で
あるか、を検証可能
•keymaster HAL Interfaceのバージョンが2.0 -> 3.0へ
Keystoreプロバイダに
お任せすれば万事解決?
NO!
Keystoreプロバイダの使用には、
注意すべき点がある
Keystoreプロバイダに
お任せすれば万事解決?
Keystoreプロバイダの注意点
バージョンによる制約
Root化された端末上では、
他アプリに鍵を利用される可能性
ユーザ操作によって鍵が消える
Keystoreプロバイダの注意点
バージョンによる制約
Root化された端末上では、
他アプリに鍵を利用される可能性
ユーザ操作によって鍵が消える
今回はこの話をします
6.0以上で旧API鍵利用時の問題
API Lv.23で鍵生成用の新API追加
→旧APIは非推奨に
旧APIで生成した鍵は、
ユーザ認証等は利用できない
 Android6.0以上だから、と思っていると痛い目を見る
 新APIへ移行を決めた段階で、旧APIで生成した鍵の置
き換えについて要検討(セキュリティレベルが変わる)
Root化端末における影響
Root権限があれば、他のアプリが作っ
た鍵をコピーして利用する攻撃が可能
鍵に紐付いたUIDを偽装してコピー可能
あくまで「利用」できるだけで、鍵その
ものを取り出せる訳では無い
 詳細は以下論文を参照
 [SPSM ‘14] Cooijmans et al. Analysis of Secure
Key Storage Solutions on Android
2.
アプリの鍵が消える時
アプリの鍵が消える時
ファクトリーリセット
アプリのアンインストール
アプリ自体が消えるから当たり前
アプリの鍵が消える時
ファクトリーリセット
アプリのアンインストール
デバイスロックの操作
ロックパターンの変更、強制リセット
新しい指紋の登録、全指紋の登録抹消
ロック操作のAndroid
Developersの記述
https://developer.android.com/training/articles/keystore.html?hl=ja
トレーニングの
「Android Keystore システム」より
ロック操作のAndroid
Developersの記述
https://developer.android.com/training/articles/keystore.html?hl=ja
トレーニングの
「Android Keystore システム」より
ロック操作のAndroid
Developersの記述
APIレベル23以降の話
https://developer.android.com/training/articles/keystore.html?hl=ja
トレーニングの
「Android Keystore システム」より
APIレベル22以前の記述
https://developer.android.com/reference/android/security/KeyPairGeneratorSpec.html
APIリファレンスの
「KeyPairGeneratorSpec」より
APIレベル22以前の記述
https://developer.android.com/reference/android/security/KeyPairGeneratorSpec.html
APIリファレンスの
「KeyPairGeneratorSpec」より
確認してみよう
ロック方法を変更することで、
鍵の状態がどのように変化するか
To↓From→ NONE PIN PASS PATTERN
NONE F F F F
PIN F F F F
PASS F F F F
PATTERN T T T T
 F:鍵が消失・無効化(復号不可)
 T:鍵は有効(復号可)
 不:変更自体が不可能
 ー:最初の生成自体が不可能
凡例
検証端末
GalaxyNexus(4.3, 4.4)、Nexus5(5.0, 5.1)、Nexus5X(6.0~8.1)
検証の組み合わせ
無し(≒スライド)、PIN、パスワード、パターンの組み合わせ。
Dorian Cussen氏のBlogの調査をベースに追試、対象拡大。
https://doridori.github.io/android-security-the-forgetful-keystore/#sthash.nKk1PAbj.dpbs
Android4.3~4.4
To↓From→ NONE PIN PASS PATTERN
NONE F F F F
PIN F F F F
PASS F F F F
PATTERN T T T T
To↓From→ NONE PIN PASS PATTERN
NONE - F F F
PIN - F F F
PASS - F F F
PATTERN - T T T
KeyPairGeneratorSpec(旧API)
 setEncryptionRequired(true)
安全なロック間の変更であっても、
パターンへの変更以外は鍵が消えてしまう
 setEncryptionRequired(false)
仕様外
Android5.0~5.1
KeyPairGeneratorSpec(旧API)
To↓From→ NONE PIN PASS PATTERN
NONE F 不 不 不
PIN F T T T
PASS F T T T
PATTERN T T T T
To↓From→ NONE PIN PASS PATTERN
NONE - 不 不 不
PIN - T T T
PASS - T T T
PATTERN - T T T
 setEncryptionRequired(true) setEncryptionRequired(false)
安全なロックスクリーンを解除すること自体、
出来なくなっている
仕様外
Android5.0~5.1
KeyPairGeneratorSpec(旧API)
To↓From→ NONE PIN PASS PATTERN
NONE - 不 不 不
PIN - T T T
PASS - T T T
PATTERN - T T T
 setEncryptionRequired(true)
Android6.0~8.1
To↓From→ NONE PIN PASS PATTERN
NONE T T T T
PIN T T T T
PASS T T T T
PATTERN T T T T
To↓From→ NONE PIN PASS PATTERN
NONE - F F F
PIN - T T T
PASS - T T T
PATTERN - T T T
 setEncryptionRequired(true) setEncryptionRequired(false)
KeyPairGeneratorSpec(旧API)
Android6.0~8.1
To↓From→ NONE PIN PASS PATTERN
NONE T T T T
PIN T T T T
PASS T T T T
PATTERN T T T T
To↓From→ NONE PIN PASS PATTERN
NONE - F F F
PIN - T T T
PASS - T T T
PATTERN - T T T
 setUserAuthenticationRequired(true) setUserAuthenticationRequired(false)
KeyGenParameterSpec(新API)
Android6.0~8.1(指紋認証)
setInvalidatedByBiometricEnrollment true*1 false
ロック方法変更無し & 指紋追加 F*2 T
ロック方法変更無し & 指紋全削除 -> 指紋追加 F*2 T
KeyGenParameterSpec(新API)
 setUserAuthenticationRequired(true)かつ
setUserAuthenticationValidatyDurationSecondsを未設定
*1:デフォルトはtrue、Android6.0ではAPIがなく、trueと同じ扱い
*2:Exceptionが発生するタイミングに、バージョンによる違いあり
Android8.0のみ暗号処理実行時(cipher.doFinal())にIllegalBlockSizeException
その他はオブジェクト初期化時(cipher.init())にkeyPermanentlyInvalidatedException
T:復号に成功
F:復号に失敗
消えるシーンの想定
setEncryptionRequired()やsetUserAuthenticationRequired()は前提
共通
作業用に一時的にロックを外す
Android4.3、4.4
ロックの方法を変えよう
(パターン→パスワードに変更)
ロックの内容を再設定しよう
(PIN/パスワードを再設定)
Android6.0以降(※)
指紋を追加したい
ユーザ操作で消えるのを
想定する必要がある
3.
消えることを見越して
アンチパターン①
不必要にローカルのみで暗号化
例:ログイン後に表示されるアプリ情報を保存
ログイン
復号
暗号化済
アプリ情報
こっちには
無いよ
鍵消失
O
K
ログイン
暗号化済
アプリ情報 復号
失敗
…
アンチパターン②
再現できない情報を暗号化
例:UUID等の生成ごとに変わるアプリ識別情報
UUID_A
復号
暗号化済
UUID_A
暗号化済
UUID_A
UUID DATA
UUID_A ・・・・
UUID_B ・・・・・
UUID DATA
UUID_A ・・・・
UUID_B ・・・・・
復号
失敗
UUID_Z(再生成、初期化後)
新しい
端末かな
鍵消失
アンチパターンからの脱出の為に
暗号化するデータの見直し
 そもそも端末で持つ必要があるか
 消えても再取得・入力可能か(同等も可)
(非推奨)やむを得ない場合,別の鍵(再取得・
導出可)で暗号化し、その鍵の保護に使う
当然データの強度はKeystoreの鍵に依らなくなる
消えることを見越した作りに
 再取得・再入力を意識したフローに
 システムだけではないサポートも
4.
まとめ
まとめ
Android Keystoreで生成した鍵
は、ユーザ操作で消失する可能性
OS Verで消失する条件が異なる
アプリ開発者は消失を前提に、
データやフローの設計が必要
暗号鍵を例に説明したが、署名等
の用途でも消失前提で設計が必要
ご清聴ありがとうございました

More Related Content

アプリの鍵が消える時_Droid kaigi2018