使用 Jetpack Security 在 Android 上进行数据加密

原标题:使用 Jetpack Security 在 Android 上进行数据加密

作者 / Jon Markoff, Staff Developer Advocate, Android Security

您是否尝试过对应用中的数据进行加密?作为开发者,您想要保护数据安全,并确保数据掌握在其合理使用者的手中。但是,大多数 Android 开发者没有专门的安全团队来帮助他们正确地加密应用数据。就算通过网络来搜索如何加密数据,您得到的答案也可能已经过时好几年了,找到的示例也难以保证准确性。

Jetpack Security (JetSec)加密库为 Files 和 SharedPreferences 对象的加密操作提供了抽象支持。该库使用了安全且运用广泛的密码学原语 (cryptographic primitives),强化了 AndroidKeyStore的使用。使用 EncryptedFile 和 EncryptedSharedPreferences 可以让您在本地保护可能包含敏感数据、API 密钥、OAuth 令牌和其他类型机密信息的文件。

  • Jetpack Security 库

    https://developer.android.google.cn/topic/security/data.md

  • 密码学原语

    https://github.com/google/tink/blob/master/docs/PRIMITIVES.md

  • AndroidKeyStore

    https://developer.android.google.cn/training/articles/keystore

Jetpack Security 库

https://developer.android.google.cn/topic/security/data.md

密码学原语

https://github.com/google/tink/blob/master/docs/PRIMITIVES.md

AndroidKeyStore

https://developer.android.google.cn/training/articles/keystore

  • Android 加密

    https://source.android.google.cn/security/encryption

  • 共享存储

    https://developer.android.google.cn/training/data-storage/shared


展开全文

Android 加密

https://source.android.google.cn/security/encryption

共享存储

https://developer.android.google.cn/training/data-storage/shared

Jetpack Security 基于 Tink,而 Tink 是 Google 的一个开源并支持跨平台的安全项目。如果您需要常规加密、混合加密或类似的安全措施,那么 Tink 可能适用于您的项目。Jetpack Security 的数据结构与 Tink 完全兼容。

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

密钥生成

在开始加密数据之前,首先要了解您的加密密钥是如何被保护的。Jetpack Security 使用一个主密钥 (master key) 对所有的子密钥 (subkey) 进行加密,子密钥则被用于每个加密操作。JetSec 在 MasterKeys 类中提供了建议的默认主密钥。这个类使用基础的 AES256-GCM 密钥,该密钥在 AndroidKeyStore 中生成并存储。AndroidKeyStore 是一个在 TEE 或 StrongBox 中存储加密密钥的容器,这使得其内容很难被提取。子密钥则存储在可配置的 SharedPreferences 对象中。

我们在 Jetpack Security 中主要使用 AES256_GCM_SPEC 规范,在一般的用例中很推荐使用该规范。AES256-GCM 是对称的,并且在现代设备上运算的速度通常很快。

对于配置更多样或处理非常敏感数据的应用,我们建议您构建自己的 KeyGenParameterSpec,选择适合您需求的选项。针对设备被 root 或遭到篡改的情况,带有 BiometricPrompt生物验证步骤的限时密钥可以提供更高级别的保护。

  • BiometricPrompt

    https://developer.android.google.cn/jetpack/androidx/releases/biometric

BiometricPrompt

https://developer.android.google.cn/jetpack/androidx/releases/biometric

重要选项:

  • userAuthenticationRequired 和 userAuthenticationValiditySeconds 可以用来创建限时密钥。限时密钥需要通过 BiometricPrompt 获得授权,才能对对称密钥进行加密和解密。
  • unlockedDeviceRequired 可以设置一个标志,用于确保在设备未解锁时不会发生密钥访问。该开关值在 Android 9 及更高版本上可用。
  • 使用 setIsStrongBoxBacked ,即可在更强大的独立芯片上运行加密操作。这会对性能带来轻微的影响,但更加安全。此功能在运行 Android 9 或更高版本的某些设备上可用。

注意: 如果您的应用需要在后台加密数据,则不应使用限时密钥或要求设备处于解锁状态,因为如果没有用户在场,您的操作将无法完成。

valadvancedKeyAlias = MasterKeys.getOrCreate(advancedSpec)

解锁限时密钥

如果您的密钥是使用以下选项创建的,则必须使用 BiometricPrompt 对设备进行授权:

  • userAuthenticationRequired 值为 true
  • userAuthenticationValiditySeconds > 0

在用户进行验证后,将基于有效秒数字段中给出时长解锁密钥。AndroidKeystore 没有用于查询密钥设置的 API,因此您的应用必须自己记录这些设置。您应该在展示授权界面的 Activity 的 onCreate方法中构建 BiometricPrompt 实例,以引导用户进行授权操作。

用来解锁限时密钥的 BiometricPrompt 代码:

valpromptInfo = PromptInfo.Builder .setTitle( “Unlock?”) .setDeion( “Would you like to unlock this key?”) .setDeviceCredentialAllowed( true) .build

valbiometricPrompt = BiometricPrompt( this, // ActivityContextCompat.getMainExecutor( this), authenticationCallback)

privatevalauthenticationCallback = object: AuthenticationCallback { overridefunonAuthenticationSucceeded(result: AuthenticationResult){ super.onAuthenticationSucceeded(result) // Unlocked — do work here.}overridefunonAuthenticati(errorCode: Int, errString: CharSequence){ super.onAuthenticati(errorCode, errString) // Handle error.}}

To use:biometricPrompt.authenticate(promptInfo)

加密文件

Jetpack Security 包含一个 EncryptedFile 类,它解决了加密文件数据的问题。与 File 相似,EncryptedFile 提供一个 FileInputStream 对象用于读取,一个 FileOutputStream 对象用于写入。我们使用遵循 OAE2 定义的 Streaming AHEAD对文件进行加密。数据被分为多个区块,并使用 AES256-GCM 进行加密,使得外界无法对其进行重组。

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

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

  • Streaming AHEAD

    https://github.com/google/tink/blob/master/docs/PRIMITIVES.md#streaming-authenticated-encryption-with-associated-data

Streaming AHEAD

https://github.com/google/tink/blob/master/docs/PRIMITIVES.md#streaming-authenticated-encryption-with-associated-data

加密 SharedPreferences

如果您的应用需要保存键值对 (例如 API 密钥),JetSec 提供了 EncryptedSharedPreferences 类,该类使用的是您所熟知的 SharedPreferences 接口。

键和值均会被加密。键使用能提供确定性密文的 AES256-SIV-CMAC进行加密;值则使用 AES256-GCM 进行加密,并绑定到加密的键。该方案允许对机要数据进行安全加密,同时仍然便于查询。

  • AES256-SIV-CMAC https://tools.ietf.org/html/rfc5297

更多资源

FileLocker是我们准备的一个示例应用,您可以在 Android Security GitHub 示例页面上找到它。这个应用很好地展示了应该如何使用 Jetpack Security 进行文件加密。

  • FileLocker https://github.com/android/security-samples/tree/master/FileLocker

祝大家加密愉快!

| 阅 读 原 文 | 进一步了解安全处理数据最佳实践

责任编辑:

Thenews.cc