在 iOS 上为 SQLite DB 派生和存储 AES 密钥

信息安全 加密 IOS 密钥生成
2021-09-12 02:17:41

我在这里阅读了有关如何在 iOS 上管理本地 SQLite 数据库加密的各种问答,据我所见,几乎每个人都同意将加密密钥存储在代码中是一个坏主意。所以,我决定不这样做。

现在,我喜欢的另一个更安全的选择是通过 TLS 从服务器发送加密密钥,并使用证书固定来帮助防止人们进行 MITM。不幸的是,这给我的情况带来了问题,因为我正在构建的应用程序需要在没有 Internet 连接的情况下完全正常运行。

我还没有看到的第三种选择是一种更复杂的安全方​​法,通过模糊(即,比在应用程序中以纯文本隐藏密码更模糊)。以下是我一直在考虑的一些选项(但对我来说都有些疑问):

  1. 使用未知但无法猜测的值(例如完成某个 API 请求所用的时间,或用户在屏幕上点击的坐标)来导出密钥。
  2. 让应用程序的用户在首次下载数据时输入不同的密码,并从中派生密钥。

我知道最佳实践要求删除派生密钥(我计划使用 PBKDF2)并保持盐 + 轮数。但是,我不想多次向用户询问密码短语(长话短说,他们只会在他们“验证”他们的设备后才提供密码,这只需要发生一次)。

结果,我认为我需要在本地存储密钥,以纯文本(或在钥匙串中,但这真的会做什么?)存储密码短语(来自上面的 1 或 2)、salt 和 rounds . 然后,该应用程序将在将密码短语输入密钥派生函数之前对其进行操作。这似乎更可取,因为存储派生密钥完全取消了所有安全性。

所以,我想知道什么。这是哑巴吗?有人确定能够在一个下午进行逆向工程吗?或者在将密钥输入密钥派生函数之前很难弄清楚应用程序是如何操纵密钥的?

1个回答

把它放在钥匙链里。这正是它的用途。它的作用是在您的应用程序不使用密钥时对其进行加密,并将对它们的访问限制在您的应用程序中。

只需让应用程序在首次使用时安全地生成一个新的随机密钥,并将其存储在钥匙串中,以便在应用程序的后续启动时重复使用。这样您就可以使用为这些目的而设计的系统,每个设备都有一个唯一的高熵密钥,并且您不会受到密码系统的固有弱点或滚动您自己的密钥的陷阱的限制-存储机制。