Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Jetpack Security

Jetpack Security

Shibuya.apk #35発表資料
Google I/O 2019にてJetpack Securityという新しいライブラリが発表されました。
なぜ必要だったか、そしてどれだけ簡単に使うことができるのかについてまとめました。

Takaki Hoshikawa

June 28, 2019
Tweet

More Decks by Takaki Hoshikawa

Other Decks in Programming

Transcript

  1. Jetpack Security (androidx-security) • Google I/O 2019で発表された暗号系ライブラリ • 暗号化処理のベストプラクティスを実装しており、高い安全性かつ高 速な処理を実現

    • Android 6.0+ で利用可能 • 利用技術 ◦ Android Keystore ◦ Tink (Google製の暗号ライブラリ) https://developer.android.com/jetpack/androidx/releases/security
  2. 暗号系機能の敷居が高い問題 ボイラープレート長い、設定項目もよくわからない val kpg: KeyPairGenerator = KeyPairGenerator.getInstance( KeyProperties.KEY_ALGORITHM_EC, "AndroidKeyStore" )

    val parameterSpec: KeyGenParameterSpec = KeyGenParameterSpec.Builder( alias, KeyProperties.PURPOSE_SIGN or KeyProperties.PURPOSE_VERIFY ).run { setDigests(KeyProperties.DIGEST_SHA256, KeyProperties.DIGEST_SHA512) build() } kpg.initialize(parameterSpec) val kp = kpg.generateKeyPair() https://developer.android.com/training/articles/keystore より引用 ECの鍵生成だけで この長さ
  3. 使い方 - ファイル暗号化 val encryptedFile = EncryptedFile.Builder( File(path), context, masterKeyAlias,

    EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB ).build() val result = runCatching { encryptedFile.openFileOutput().use { it.write(text.toByteArray(Charset.forName("UTF-8"))) it.flush() } }
  4. 使い方 - ファイル暗号化 val encryptedFile = EncryptedFile.Builder( File(path), context, masterKeyAlias,

    EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB ).build() val result = runCatching { encryptedFile.openFileOutput().use { it.write(text.toByteArray(Charset.forName("UTF-8"))) it.flush() } } 先程生成したキー のエイリアス
  5. 使い方 - ファイル暗号化 val encryptedFile = EncryptedFile.Builder( File(path), context, masterKeyAlias,

    EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB ).build() val result = runCatching { encryptedFile.openFileOutput().use { it.write(text.toByteArray(Charset.forName("UTF-8"))) it.flush() } } 同じく選択肢はこれしか用意されていない
  6. 使い方 - ファイル暗号化 val encryptedFile = EncryptedFile.Builder( File(path), context, masterKeyAlias,

    EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB ).build() val result = runCatching { encryptedFile.openFileOutput().use { it.write(text.toByteArray(Charset.forName("UTF-8"))) it.flush() } } 通常のファイル読み書きと ほぼ同じ記述で書ける
  7. 使い方 - ファイル復号 val encryptedFile = EncryptedFile.Builder( File(path), context, masterKeyAlias,

    EncryptedFile.FileEncryptionScheme.AES256_GCM_HKDF_4KB ).build() val result = runCatching { encryptedFile.openFileInput().use { it.bufferedReader().readText() } }
  8. 使い方 - SharedPreference val pref: SharedPreference = EncryptedSharedPreferences.create( "pref_file_name", MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),

    context, EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM )
  9. 使い方 - SharedPreference val pref: SharedPreference = EncryptedSharedPreferences.create( "pref_file_name", MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC),

    context, EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM ) いつものSharedPreferenceインターフェースを 実装しているのであとは普段どおり使える
  10. 暗号化されたPreference XML <?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map> <string name="AVh0wrPyiwYcYEfSJpVUvVTuXJcoRf/B">AV1M1P7NgVsTKwwfb4nesoj+Brz...</string>

    <string name="__androidx_security_crypto_encrypted_prefs_key_keyset__">12a901ba5467eb84...</string> <string name="__androidx_security_crypto_encrypted_prefs_value_keyset__">1288012427b544ed...</string> </map>
  11. 暗号化されたPreference XML <?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map> <string name="AVh0wrPyiwYcYEfSJpVUvVTuXJcoRf/B">AV1M1P7NgVsTKwwfb4nesoj+Brz...</string>

    <string name="__androidx_security_crypto_encrypted_prefs_key_keyset__">12a901ba5467eb84...</string> <string name="__androidx_security_crypto_encrypted_prefs_value_keyset__">1288012427b544ed...</string> </map> Preferenceのkey, valueそれぞれを暗号化 するための共通鍵を更に暗号化したもの
  12. 暗号化されたPreference XML <?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map> <string name="AVh0wrPyiwYcYEfSJpVUvVTuXJcoRf/B">AV1M1P7NgVsTKwwfb4nesoj+Brz...</string>

    <string name="__androidx_security_crypto_encrypted_prefs_key_keyset__">12a901ba5467eb84...</string> <string name="__androidx_security_crypto_encrypted_prefs_value_keyset__">1288012427b544ed...</string> </map> key: foo, value: bar が暗号化されたもの
  13. 補足 - なぜ高速? A. プロセス間通信を最小限に留めているから (多分) Android Keystoreで暗号化・復号する場合プロセス間通信となるため少し遅 くなる。 Jetpack

    Securityでは、直接ファイルをKeystoreで暗号化するのではなく、 別のAESキーを生成して暗号化や復号を行う。 そのキーをKeystoreで暗号化し、SharedPreferenceに保存している。
  14. 補足 - Tinkとは? A. 多言語 & クロスプラットフォームな暗号ライブラリ Java & Android,

    C++, Obj-C対応 Go, JavaScript向けに開発中 https://github.com/google/tink