Data Encryption on Android with Jetpack Security

栏目: IT技术 · 发布时间: 4年前

内容简介:Have you ever tried to encrypt data in your app? As a developer, you want to keep data safe, and in the hands of the party intended to use. But if you’re like most Android developers, you don’t have a dedicated security team to help encrypt your app’s data

Data Encryption on Android with Jetpack Security

Have you ever tried to encrypt data in your app? As a developer, you want to keep data safe, and in the hands of the party intended to use. But if you’re like most Android developers, you don’t have a dedicated security team to help encrypt your app’s data properly. By searching the web to learn how to encrypt data, you might get answers that are several years out of date and provide incorrect examples.

The Jetpack Security (JetSec) crypto library provides abstractions for encrypting Files and SharedPreferences objects. The library promotes the use of the AndroidKeyStore while using safe and well-known cryptographic primitives . Using EncryptedFile and EncryptedSharedPreferences allows you to locally protect files that may contain sensitive data, API keys, OAuth tokens, and other types of secrets.

Why would you want to encrypt data in your app? Doesn’t Android, since 5.0, encrypt the contents of the user's data partition by default? It certainly does, but there are some use cases where you may want an extra level of protection. If your app uses shared storage , you should encrypt the data. In the app home directory, your app should encrypt data if your app handles sensitive information including but not limited to personally identifiable information (PII), health records, financial details, or enterprise data. When possible, we recommend that you tie this information to biometrics for an extra level of protection.

Jetpack Security is based on Tink , an open-source, cross-platform security project from Google. Tink might be appropriate if you need general encryption, hybrid encryption, or something similar. Jetpack Security data structures are fully compatible with Tink.

Key Generation

Before we jump into encrypting your data, it’s important to understand how your encryption keys will be kept safe. Jetpack Security uses a master key , which encrypts all subkeys that are used for each cryptographic operation. JetSec provides a recommended default master key in the MasterKeys class. This class uses a basic AES256-GCM key which is generated and stored in the AndroidKeyStore. The AndroidKeyStore is a container which stores cryptographic keys in the TEE or StrongBox, making them hard to extract. Subkeys are stored in a configurable SharedPreferences object.

Primarily, we use the AES256_GCM_SPEC specification in Jetpack Security, which is recommended for general use cases. AES256-GCM is symmetric and generally fast on modern devices.

val keyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)

For apps that require more configuration, or handle very sensitive data, it’s recommended to build your KeyGenParameterSpec , choosing options that make sense for your use. Time-bound keys with BiometricPrompt can provide an extra level of protection against rooted or compromised devices.

Important options:

  • userAuthenticationRequired() and userAuthenticationValiditySeconds() can be used to create a time-bound key. Time-bound keys require authorization using BiometricPrompt for both encryption and decryption of symmetric keys.
  • unlockedDeviceRequired() sets a flag that helps ensure key access cannot happen if the device is not unlocked. This flag is available on Android Pie and higher.
  • Use setIsStrongBoxBacked() , to run crypto operations on a stronger separate chip. This has a slight performance impact, but is more secure. It’s available on some devices that run Android Pie or higher.

Note:If your app needs to encrypt data in the background, you should not use time-bound keys or require that the device is unlocked, as you will not be able to accomplish this without a user present.

// Custom Advanced Master Key
val advancedSpec = KeyGenParameterSpec.Builder(
    "master_key",
    KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT
).apply {
    setBlockModes(KeyProperties.BLOCK_MODE_GCM)
    setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
    setKeySize(256)
    setUserAuthenticationRequired(true)
    setUserAuthenticationValidityDurationSeconds(15) // must be larger than 0
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
        setUnlockedDeviceRequired(true)
        setIsStrongBoxBacked(true)
    }
}.build()

val advancedKeyAlias = MasterKeys.getOrCreate(advancedSpec)

Unlocking time-bound keys

You must use BiometricPrompt to authorize the device if your key was created with the following options:

userAuthenticationRequired
userAuthenticationValiditySeconds 

After the user authenticates, the keys are unlocked for the amount of time set in the validity seconds field. The AndroidKeystore does not have an API to query key settings, so your app must keep track of these settings. You should build your BiometricPrompt instance in the onCreate() method of the activity where you present the dialog to the user.

BiometricPrompt code to unlock time-bound keys

// Activity.onCreate

val promptInfo = PromptInfo.Builder()
    .setTitle("Unlock?")
    .setDescription("Would you like to unlock this key?")
    .setDeviceCredentialAllowed(true)
    .build()

val biometricPrompt = BiometricPrompt(
    this, // Activity
    ContextCompat.getMainExecutor(this),
    authenticationCallback
)

private val authenticationCallback = object : AuthenticationCallback() {
        override fun onAuthenticationSucceeded(
            result: AuthenticationResult
        ) {
            super.onAuthenticationSucceeded(result)
            // Unlocked -- do work here.
        }
        override fun onAuthenticationError(
            errorCode: Int, errString: CharSequence
        ) {
            super.onAuthenticationError(errorCode, errString)
            // Handle error.
        }
    }

To use:
biometricPrompt.authenticate(promptInfo)

Encrypt Files

Jetpack Security includes an EncryptedFile class, which removes the challenges of encrypting file data. Similar to File, EncryptedFile provides a FileInputStream object for reading and a FileOutputStream object for writing. Files are encrypted using Streaming AEAD, which follows the OAE2 definition . The data is divided into chunks and encrypted using AES256-GCM in such a way that it's not possible to reorder.

val secretFile = File(filesDir, "super_secret")
val encryptedFile = EncryptedFile.Builder(
    secretFile,
    applicationContext,
    advancedKeyAlias,
    FileEncryptionScheme.AES256_GCM_HKDF_4KB)
    .setKeysetAlias("file_key") // optional
    .setKeysetPrefName("secret_shared_prefs") // optional
    .build()

encryptedFile.openFileOutput().use { outputStream ->
    // Write data to your encrypted file
}

encryptedFile.openFileInput().use { inputStream ->
    // Read data from your encrypted file
}

Encrypt SharedPreferences

If your application needs to save Key-value pairs - such as API keys - JetSec provides the EncryptedSharedPreferences class, which uses the same SharedPreferences interface that you’re used to.

Both keys and values are encrypted. Keys are encrypted using AES256-SIV-CMAC , which provides a deterministic cipher text; values are encrypted with AES256-GCM and are bound to the encrypted key. This scheme allows the key data to be encrypted safely, while still allowing lookups.

EncryptedSharedPreferences.create(
    "my_secret_prefs",
    advancedKeyAlias,
    applicationContext,
    PrefKeyEncryptionScheme.AES256_SIV,
    PrefValueEncryptionScheme.AES256_GCM
).edit {
    // Update secret values
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

数学之美 (第二版)

数学之美 (第二版)

吴军 / 人民邮电出版社 / 2014-11 / 49.00元

几年前,“数学之美”系列文章原刊载于谷歌黑板报,获得上百万次点击,得到读者高度评价。读者说,读了“数学之美”,才发现大学时学的数学知识,比如马尔可夫链、矩阵计算,甚至余弦函数原来都如此亲切,并且栩栩如生,才发现自然语言和信息处理这么有趣。 在纸本书的创作中,作者吴军博士几乎把所有文章都重写了一遍,为的是把高深的数学原理讲得更加通俗易懂,让非专业读者也能领略数学的魅力。读者通过具体的例子学到的......一起来看看 《数学之美 (第二版)》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具