Flet SecureStorage 的 KeyCipherAlgorithm 详解:Android KeyStore 密钥加密算法选择指南
【免费下载链接】fletBuild realtime web, mobile and desktop apps in Python only. No frontend experience required.项目地址: https://gitcode.com/gh_mirrors/fl/flet
KeyCipherAlgorithm是 Fletflet-secure-storage扩展中用于控制Android KeyStore 密钥加密(Key Wrapping)算法的枚举类型,它决定了敏感数据在 Android 设备上加密时的密钥保护策略。本文将围绕该枚举的三个成员展开,结合仓库源码解析其安全语义、生物识别兼容性差异,并给出在AndroidOptions中实际配置的完整示例,帮助你为不同安全需求的应用场景选择正确的算法。
KeyCipherAlgorithm 是什么
在 Flet 的 Android 安全存储体系里,存储链路分为两层加密:一层是「数据加密」——使用StorageCipherAlgorithm加密实际存储的内容;另一层是「密钥加密」——使用KeyCipherAlgorithm加密/包裹(wrap)那把用于加密数据的对称密钥(secret key)。后者之所以必要,是因为 Android KeyStore 本身不直接暴露密钥明文,需要通过指定的密码学算法把密钥安全地「包裹」起来再持久化。
KeyCipherAlgorithm枚举定义于 sdk/python/packages/flet-secure-storage/src/flet_secure_storage/types.py:
class KeyCipherAlgorithm(Enum): """ Algorithm used to encrypt/wrap the secret key in Android KeyStore. Different algorithms provide different security guarantees and compatibility levels: - RSA algorithms wrap the AES encryption key with RSA (no biometric support) - AES algorithm stores the key directly in Android KeyStore (supports biometric authentication) See the [AndroidOptions] class for usage examples and combinations. """ RSA_ECB_PKCS1_PADDING = "RSA_ECB_PKCS1Padding" RSA_ECB_OAEP_WITH_SHA256_AND_MGF1_PADDING = "RSA_ECB_OAEPwithSHA_256andMGF1Padding" AES_GCM_NO_PADDING = "AES_GCM_NoPadding"从源码 docstring 可以提炼出核心分类逻辑:RSA 系列算法用 RSA 公钥去包裹 AES 加密密钥(不支持生物识别);AES 算法则把密钥直接存放在 Android KeyStore 中(支持生物识别认证)。
三个枚举成员的语义与适用场景
| 枚举成员 | 底层算法 | API 要求 | 生物识别 | 定位 |
|---|---|---|---|---|
RSA_ECB_PKCS1_PADDING | RSA/ECB/PKCS1Padding | 无特殊要求 | 不支持 | 旧版向后兼容 |
RSA_ECB_OAEP_WITH_SHA256_AND_MGF1_PADDING | RSA/ECB/OAEPWithSHA-256AndMGF1Padding | API 23+ | 不支持 | 默认且推荐的 RSA 方案 |
AES_GCM_NO_PADDING | AES/GCM/NoPadding | API 23+ 基础使用,API 28+ 强制生物识别 | 支持 | 需要生物识别认证时使用 |
RSA_ECB_PKCS1_PADDING:旧版兼容方案
源码注释将其描述为 “Legacy RSA/ECB/PKCS1Padding for backwards compatibility”,即用于向后兼容的历史方案。PKCS1 v1.5 padding 属于较早期的 RSA 填充标准,虽然实现简单、兼容面广,但相比 OAEP 在安全性设计上更为陈旧。仅在需要兼容旧版本应用写入的数据时才应考虑,新项目不建议主动选择。
RSA_ECB_OAEP_WITH_SHA256_AND_MGF1_PADDING:默认推荐方案
源码注释明确给出了两条关键信息:
RSA/ECB/OAEPWithSHA-256AndMGF1Padding (API 23+). This is the default and recommended algorithm for most use cases. Provides strong authenticated encryption without biometrics.
- 它是
AndroidOptions.key_cipher_algorithm的默认值,这一点在 types.py 中通过字段默认值直接体现:key_cipher_algorithm: KeyCipherAlgorithm = ( KeyCipherAlgorithm.RSA_ECB_OAEP_WITH_SHA256_AND_MGF1_PADDING ) - OAEP(Optimal Asymmetric Encryption Padding)配合 SHA-256 与 MGF1 掩码生成函数,提供了经过认证的强加密能力,是 RSA 系中兼顾安全与兼容的均衡选择。
- 由于使用 RSA 包裹密钥,无法与生物识别认证联动。
AES_GCM_NO_PADDING:支持生物识别的方案
源码注释说明:
AES/GCM/NoPadding for KeyStore-based key wrapping (supports biometrics). Use this algorithm when you need biometric authentication support. Requires API 23+ for basic use, API 28+ for enforced biometric authentication.
- 该方案直接把 AES 密钥存储在 Android KeyStore 中,绕开了 RSA 的包裹步骤,因此能够与系统生物识别(指纹/面容/PIN)认证机制协同工作。
- API 23(Android 6.0)以上可用于基础场景;若要强制生物识别认证,则需要 API 28(Android 9)及以上。
- GCM 模式属于 AEAD(带关联数据的认证加密),同时提供机密性与完整性保护。
在 AndroidOptions 中配置 KeyCipherAlgorithm
KeyCipherAlgorithm并非独立使用,而是作为 AndroidOptions 的key_cipher_algorithm字段被消费。完整可用的AndroidOptions字段如下(源自 types.py):
| 字段 | 默认值 | 说明 |
|---|---|---|
reset_on_error | True | 检测到错误时自动重置全部数据,防止未知密钥导致致命错误(注意:数据会被永久清除) |
migrate_on_algorithm_change | True | 加密算法变更时自动把存量数据迁移到新算法,保护数据不丢失 |
enforce_biometrics | False | 是否强制生物识别/PIN 认证;为True时若设备未录入生物信息会抛异常 |
key_cipher_algorithm | RSA_ECB_OAEP_WITH_SHA256_AND_MGF1_PADDING | 密钥加密(包裹)算法,即本文主题 |
storage_cipher_algorithm | AES_GCM_NO_PADDING | 数据加密算法 |
shared_preferences_name | None | SharedPreferences 数据库名称 |
preferences_key_prefix | None | 存储键前缀(自动追加下划线),改变后无法访问旧数据 |
biometric_prompt_title | "Authenticate to access" | 生物识别弹窗标题 |
biometric_prompt_subtitle | "Use biometrics or device credentials" | 生物识别弹窗副标题 |
仓库自带的官方示例 sdk/python/examples/extensions/secure_storage/secure_storage/main.py 展示了一套「AES-GCM + 生物识别」的完整配置:
import flet as ft import flet_secure_storage as fss storage = fss.SecureStorage( web_options=fss.WebOptions( db_name="customstorage", public_key="publickey", wrap_key=base64.urlsafe_b64encode(os.urandom(32)).decode(), wrap_key_iv=base64.urlsafe_b64encode(os.urandom(16)).decode(), ), android_options=fss.AndroidOptions( reset_on_error=True, migrate_on_algorithm_change=True, enforce_biometrics=True, key_cipher_algorithm=fss.KeyCipherAlgorithm.AES_GCM_NO_PADDING, storage_cipher_algorithm=fss.StorageCipherAlgorithm.AES_GCM_NO_PADDING, ), )这里key_cipher_algorithm=AES_GCM_NO_PADDING与enforce_biometrics=True是配套组合:只有当密钥直接存放于 KeyStore(AES 方案)时,生物识别认证才能约束密钥的解锁使用。
算法选择的决策要点
不需要生物识别:优先用默认 RSA-OAEP
对于大多数普通敏感数据(如 token、会话凭据),使用默认的RSA_ECB_OAEP_WITH_SHA256_AND_MGF1_PADDING即可。它无需额外依赖用户录入生物信息,在 API 23+ 设备上提供强认证加密,且是经过广泛验证的默认路径。
需要生物识别保护:切换为 AES-GCM
当业务要求读取敏感数据前必须通过指纹/面容认证(例如支付凭据、私密笔记)时,应改用AES_GCM_NO_PADDING,并同时设置enforce_biometrics=True。需要留意:
- 设备 API 版本必须 ≥ 23;强制生物识别场景需 ≥ 28。
- 若
enforce_biometrics=True而设备未录入任何生物信息/PIN,插件会抛出异常(而不会静默降级)。
算法切换与存量数据迁移
修改key_cipher_algorithm会影响已写入数据的可读性,仓库为此提供了两个配套开关:
migrate_on_algorithm_change=True(默认):算法变更后自动把存量密文迁移到新算法,保障升级平滑;reset_on_error=True(默认):若迁移失败或遇到无法识别的密钥,自动重置全部数据以避免致命错误——代价是数据被永久清除。
如果你的应用禁止数据丢失,应在切换算法前做好备份或评估迁移行为;若允许清空重来,保持两个开关为默认值即可获得最省心的体验。
底层实现链路:Python 枚举如何驱动 Dart 插件
KeyCipherAlgorithm不是凭空生效的:Python 侧的枚举值最终会经过序列化传递到 Flutter 插件层执行真正的 KeyStore 操作。在 Dart 侧,secure_storage.dart 提供了对应的解析函数:
KeyCipherAlgorithm? parseKeyCipherAlgorithm(String? value, [KeyCipherAlgorithm? defaultValue]) { if (value == null) return defaultValue; return KeyCipherAlgorithm.values.firstWhereOrNull( (e) => e.name.toLowerCase() == value.toLowerCase() ) ?? defaultValue; }而 parseAndroidOptions 在构造 Flutter 插件选项时会读取key_cipher_algorithm字段,并在 Python 侧未显式指定时回落到默认值RSA_ECB_OAEPwithSHA_256andMGF1Padding——这与 Python 端AndroidOptions字段的默认值保持一致,两端默认策略是对齐的。解析采用大小写不敏感匹配,因此从 Python 传入的枚举字符串(如"RSA_ECB_OAEPwithSHA_256andMGF1Padding")能够被正确识别。
与 StorageCipherAlgorithm 的分工
容易混淆的是 StorageCipherAlgorithm,它控制的是数据本身的加密算法(默认AES_GCM_NO_PADDING,另有旧版AES_CBC_PKCS7_PADDING仅作向后兼容)。两者分工如下:
key_cipher_algorithm:决定「加密数据所用的密钥」如何被 KeyStore 包裹与保护(本文主题);storage_cipher_algorithm:决定「落盘数据」用什么算法加密。
它们可以独立配置,但现代应用应同时优先选择 AES-GCM 系:数据侧用AES_GCM_NO_PADDING,密钥侧在需要生物识别时同样用AES_GCM_NO_PADDING(如官方示例所示)。
使用前提与平台提醒
KeyCipherAlgorithm仅作用于 Android 平台。整个flet-secure-storage服务支持 Windows、macOS、Linux、iOS、Android 与 Web 全平台(详见 securestorage/index.md),其他平台分别使用 Keychain(iOS/macOS)、Windows Credential Manager、libsecret(Linux)等原生机制,与本枚举无关。另外,在 Linux 上构建需要libsecret-1-dev、运行需要libsecret-1-0以及一个 keyring 服务(如 gnome-keyring 或 kwalletmanager),这是使用该扩展在 Linux 桌面端的先决条件。
总而言之,在 Flet 的 Android 安全存储方案中,KeyCipherAlgorithm是一把决定密钥保护策略的「钥匙」:默认的 RSA-OAEP 方案安全均衡、开箱即用;AES-GCM 方案则是启用生物识别认证的必经之路。结合AndroidOptions中的enforce_biometrics、migrate_on_algorithm_change与reset_on_error三个开关,即可在安全强度、兼容性与数据迁移之间做出适合自己应用的选择。
【免费下载链接】fletBuild realtime web, mobile and desktop apps in Python only. No frontend experience required.项目地址: https://gitcode.com/gh_mirrors/fl/flet
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考