$30 off During Our Annual Pro Sale. View Details »

Android Security(Security library, Biometric Auth)

TaeHwan
December 21, 2019

Android Security(Security library, Biometric Auth)

TaeHwan

December 21, 2019
Tweet

More Decks by TaeHwan

Other Decks in Programming

Transcript

  1. Android Dev Summit

    2019 extended Seoul
    AndroidX Security library
    Android Security
    kakaopay

    GDG Seoul Organizer

    Taehwan

    View Slide

  2. য়ט ঌইࠅ ղਊ
    • AndroidX Security Library ࣗѐ

    • Library ࢎਊߨ

    • ࢎਊೞݶࢲ ઱੄ೡ ੼

    View Slide

  3. ੉ ߊ಴ীࢲ ঌ ࣻ হח Ѫٜ
    • Security Libraryਸ ઁ৻ ೠ ࠁউ਷ ঌ ࣽ হ׮.

    View Slide

  4. ੉ ੗ܐٜਸ ଵҊೞࣁਃ
    • ࠶۽Ӓ

    • https://thdev.tech/android/2019/12/21/Android-Security-Library

    • ਬౚ࠳

    • https://www.youtube.com/watch?v=0uG_RKiDmQY

    • https://youtu.be/W3mwSnF1n50

    • ѐߊ ޙࢲ

    • https://developer.android.com/guide/topics/security/cryptography

    • https://developer.android.com/training/articles/keystore

    • https://github.com/google/tink

    • https://developer.android.com/topic/security/data

    • https://developer.android.com/training/sign-in/biometric-auth

    View Slide

  5. Android Dev Summit

    2019 extended Seoul
    Security Library

    View Slide

  6. Android Security

    View Slide

  7. Security Library
    • MinSdk

    • API 23 - Android 6.0 (Marshmallow)

    • Last version

    • alpha2 (May 23, 2019)

    • ઁҕೞח Ѫٜ

    • ঐഐച ҙ۲ : EncryptedFile, EncryptedSharedPreferences

    • KeyAlias ࢤࢿ : Android KeyStore ੉ਊೠ MasterKeys generator
    https://developer.android.com/guide/topics/security/cryptography

    View Slide

  8. ঐഐച ҙ۲(Google Tink ࢎਊ)
    • Open source project

    • Multi-language(Java, C++, Obj-c ١)

    • cross-platform ജ҃ ૑ਗ
    https://github.com/google/tink

    View Slide

  9. Android Dev Summit

    2019 extended Seoul
    Use Security library

    View Slide

  10. Use Security library
    dependencies {

    implementation "androidx.security:security-crypto:1.0.0-alpha02"

    }

    View Slide

  11. ߡ੹੉ ݏ૑ ঋਵݶ
    Manifest merger failed : uses-sdk:minSdkVersion 21 cannot be smaller
    than version 23 declared in library



    Suggestion: use a compatible library with a minSdk of at most 21,

    or increase this project's minSdk version to at least 23,

    or use tools:overrideLibrary="androidx.security" to force usage
    (may lead to runtime failures)

    View Slide

  12. Encrypted

    Shared

    Preferences

    View Slide

  13. EncryptedSharedPreferences
    private val sharedPreferences: SharedPreferences by lazy {

    val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC

    val masterKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec)

    EncryptedSharedPreferences.create(

    "security_test",

    masterKeyAlias,

    requireContext(),

    EncryptedSharedPreferences

    .PrefKeyEncryptionScheme.AES256_SIV,

    EncryptedSharedPreferences

    .PrefValueEncryptionScheme.AES256_GCM)

    }

    View Slide

  14. private val sharedPreferences: SharedPreferences by lazy {

    val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC

    val masterKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec)

    EncryptedSharedPreferences.create(

    "security_test",

    masterKeyAlias,

    requireContext(),

    EncryptedSharedPreferences

    .PrefKeyEncryptionScheme.AES256_SIV,

    EncryptedSharedPreferences

    .PrefValueEncryptionScheme.AES256_GCM)

    }
    EncryptedSharedPreferences
    1. Alias ࢤࢿ ః spec ੿੄
    2. Alias ࢤࢿ
    3. ୡӝച
    4. Preferences ౵ੌ ݺ
    5. ࢤࢿೠ Alias
    6. Keyী ؀ೠ ঐഐച ߑध ૑੿
    7. Valueী ؀ೠ ঐഐച ߑध ૑੿

    View Slide

  15. ௏٘ ੸ਊ
    sharedPreferences

    .edit()

    .putString("edit", binding.editQuery.text.toString())

    .apply()

    sharedPreferences.getString("edit", "")
    binding.tvShowQuery.text =

    View Slide

  16. ز੘ ഛੋ
    • Input

    • Encryption

    • SharedPreferences

    • Decryption

    • TextView.text update

    View Slide

  17. ؘ੉ఠ ਤ஖ ഛੋ
    • Device File Explorerܳ ੉ਊೠ ഛੋ

    • data/data/packageName/shared_prefs/fileName.xml

    View Slide

  18. ੿݈ ੜ ঐഐചغ঻ա?




    name=“__androidx_security_crypto_encrypted_prefs_key_keyset__”>12a9012625bdf450e290a64e2d986fef7dfc1eeb
    2bbd155284109e023154109143a090d5cdcd013d7baa0e5a8a711bc2be890…001

    name=“__androidx_security_crypto_encrypted_prefs_value_keyset__”>128801a126068a44b9c8d90f866c9ad39506d
    7c878dcd1933afb0555993979cee6078d131cb2b197439c7054….e9b90072001

    AXIG/
    0eBMc6MsQjaAbOQUY8QijYBYnl4TKWnH+dcNIjKBfZqlyJtgbcMEcorjP71Vcc=


    Key editী ؀ೠ key/value

    View Slide

  19. EncryptedFile

    View Slide

  20. EncryptedFile
    val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC

    val masterKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec)

    val fileToRead = "my_sensitive_data.txt"

    val encryptedFile = EncryptedFile.Builder(

    File(requireContext().cacheDir, fileToRead),

    requireContext(),

    masterKeyAlias,

    EncryptedFile

    .FileEncryptionScheme

    .AES256_GCM_HKDF_4KB

    ).build()

    View Slide

  21. EncryptedFile
    val keyGenParameterSpec = MasterKeys.AES256_GCM_SPEC

    val masterKeyAlias = MasterKeys.getOrCreate(keyGenParameterSpec)

    val fileToRead = "my_sensitive_data.txt"

    val encryptedFile = EncryptedFile.Builder(

    File(requireContext().cacheDir, fileToRead),

    requireContext(),

    masterKeyAlias,

    EncryptedFile

    .FileEncryptionScheme

    .AES256_GCM_HKDF_4KB

    ).build()
    1. Alias ࢤࢿ ః spec ੿੄
    2. Alias ࢤࢿ
    3. ࢎਊೡ file name
    4. EncryptedFile ୡӝച
    5. ࢎਊೡ ౵ੌ ୡӝച
    6. Key Alias
    7. ࢎਊೡ ঐഐച ؘ੉ఠ

    View Slide

  22. Read/Write
    encryptedFile.openFileOutput().bufferedWriter().use {
    it.write(binding.editQuery.text.toString())
    }
    val content = encryptedFile.openFileInput()
    .bufferedReader().useLines { lines ->
    lines.fold(" ") { working, line ->
    "$working $line"
    }
    }
    // Use content

    View Slide

  23. ز੘ ഛੋ
    • Input

    • Encryption

    • SharedPreferences

    • Decryption

    • TextView.text update

    View Slide

  24. ؘ੉ఠ ਤ஖ ഛੋ
    • Device File Explorerܳ ੉ਊೠ ഛੋ

    • ੷੢ೠ ҃۽۽ ੉ز

    • ৈӝࢲח data/data/packageName/cache/fileName.txt

    View Slide

  25. ੿݈ ੜ ঐഐചغ঻ա?

    View Slide

  26. Warning

    View Slide

  27. KeyAlias ߸҃?
    @NonNull

    public static String getOrCreate(

    @NonNull KeyGenParameterSpec spec)

    throws GeneralSecurityException, IOException {

    validate(spec);

    if (!MasterKeys.keyExists(spec.getKeystoreAlias())) {

    generateKey(spec);

    }

    return spec.getKeystoreAlias();

    }
    • masterKeyAliasח String ߸ࣻ੉׮

    • ߸҃ оמೞҊ, ز੘ী ޙઁহ׮.

    • ೞ૑݅ MasterKeys ࢎਊਸ ӂ੢ validate(spec);

    if (!MasterKeys.keyExists(spec.getKeystoreAlias())) {

    generateKey(spec);

    }

    View Slide

  28. EncryptedFile
    • File openFileOutput ࢎਊ द ઱੄೧ঠ ೠ׮.

    • ੉޷ ࢤࢿػ زੌ ౵ੌ੉ ੓ਵݶ Exception ߊࢤ

    View Slide

  29. EncryptedFile
    @NonNull

    public FileOutputStream openFileOutput()

    throws GeneralSecurityException, IOException {

    if (mFile.exists()) {

    throw new IOException("output file already exists, please use a new file: "

    + mFile.getName());

    }

    FileOutputStream fileOutputStream = new FileOutputStream(mFile);

    OutputStream encryptingStream =

    mStreamingAead.newEncryptingStream(

    fileOutputStream,

    mFile.getName().getBytes(UTF_8));

    return new EncryptedFileOutputStream(fileOutputStream.getFD(), encryptingStream);

    }

    View Slide

  30. EncryptedFile
    @NonNull

    public FileOutputStream openFileOutput()

    throws GeneralSecurityException, IOException {

    if (mFile.exists()) {

    throw new IOException("output file already exists, please use a new file: "

    + mFile.getName());

    }

    FileOutputStream fileOutputStream = new FileOutputStream(mFile);

    OutputStream encryptingStream =

    mStreamingAead.newEncryptingStream(

    fileOutputStream,

    mFile.getName().getBytes(UTF_8));

    return new EncryptedFileOutputStream(fileOutputStream.getFD(), encryptingStream);

    }

    if (mFile.exists()) {

    throw new IOException("output file already exists, please use a new file: "

    + mFile.getName());

    } زੌ ౵ੌ ݺਵ۽ Output ೡ ҃਋ Exception ߊࢤ

    View Slide

  31. ౵ੌ ॳӝ ೧Ѿ ߑߨ
    val file = File(requireContext()

    .cacheDir, fileToRead)

    if (file.exists()) {

    file.delete()

    }
    • ӝઓ ౵ੌਸ ઁѢ

    • ৮੹ೠ ؘ੉ఠ ࣚप ઱੄ ೙ਃ

    • ӝઓ ౵ੌਸ ੍য ׮द ੷੢

    • ࢜۽਍ ؘ੉ఠ append റ ੷੢

    View Slide

  32. Biometric

    Authentication

    View Slide

  33. Biometric Authentication
    • MinSdk

    • API 23 - Android 6.0
    (Marshmallow)

    • Last version

    • 1.0.1 (December 18, 2019)
    https://developer.android.com/training/sign-in/biometric-auth

    View Slide

  34. Use Security library
    dependencies {

    implementation "androidx.biometric:biometric:1.0.1"

    }

    View Slide

  35. Biometric Authentication
    val biometricPrompt = BiometricPrompt.PromptInfo.Builder()

    .setTitle("Biometric login for my app")

    .setSubtitle("Log in using your biometric credential")

    .setNegativeButtonText("Use account password")

    .setConfirmationRequired(true)

    .build()

    val biometric = BiometricPrompt(

    requireActivity(),

    ContextCompat.getMainExecutor(requireContext()),

    listener

    )

    biometric.authenticate(biometricPrompt)

    View Slide

  36. Biometric Authentication
    val biometricPrompt = BiometricPrompt.PromptInfo.Builder()

    .setTitle("Biometric login for my app")

    .setSubtitle("Log in using your biometric credential")

    .setNegativeButtonText("Use account password")

    .build()

    val biometric = BiometricPrompt(

    requireActivity(),

    ContextCompat.getMainExecutor(requireContext()),

    listener

    )

    biometric.authenticate(biometricPrompt)
    .setConfirmationRequired(true) ঴ҷ ੋध੄ ҃਋ ୶о ߡౡ ഝࢿച ২࣌ ࢎਊ

    View Slide

  37. Biometric Authentication
    val listener = object : BiometricPrompt.AuthenticationCallback() {

    override fun onAuthenticationError(errorCode: Int, errString: CharSequence) {

    super.onAuthenticationError(errorCode, errString)

    android.util.Log.i("TEMP", "Unlock error errorCode $errorCode errString $errString")

    }

    override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult) {

    super.onAuthenticationSucceeded(result)

    // Unlocked

    android.util.Log.i("TEMP", "Unlock success")

    }

    override fun onAuthenticationFailed() {

    super.onAuthenticationFailed()

    android.util.Log.i("TEMP", "Unlock failed")

    }

    }

    View Slide

  38. Biometric Authentication
    • onAuthenticationError

    • ஂࣗ, ࠺޻ߣഐ ࢎਊ, ײӝ ١ ݽٚ ী۞ח ৈӝ۽

    • onAuthenticationSucceeded

    • Biometric ੋૐ ࢿҕ द ৈӝ۽

    • onAuthenticationFailed

    • ੋૐ җ੿ীࢲ पಁೠ ҃਋ ৈӝ۽

    View Slide

  39. Android Dev Summit

    2019 extended Seoul
    End
    Taehwan

    [email protected]

    View Slide