7

我有一个关于核心数据加密的问题。我将一些敏感的用户数据存储在 Core Data SQLite 数据库中。关键值都是可转换的,我正在使用 AES256 对它们进行“动态”加密和解密,包括每个值的单独 IV。加密密钥是用户选择的密码的 SHA512 哈希。到目前为止,这非常有效。

现在关于用户密码。当用户启动应用程序时,系统会要求他输入密码。密码使用 SHA512 进行哈希处理并存储在 iOS 钥匙串中。对于每个写入或读取操作,NSValueTransformer 将从钥匙串中获取密码。如果应用程序正在关闭,我会从钥匙串中删除密码哈希。

在我的核心数据数据库中,我有一个特殊的实体,它有一个随机数!= 0,因为它是唯一的值。为了测试用户是否输入了正确的密码,我获取了这个实体并读取了这个数字。如果是=!0,我知道密码是正确的,因为当解密失败时 NSValueTransformer 总是返回 0。

现在我的实际问题是:您认为这是一种很好的加密方法吗?如果输入的密码正确,您将如何测试?

我有点担心在应用程序运行时将密码哈希存储在钥匙串中会使一切变慢,因为 NSValueTransformer 必须一直访问钥匙串。将密码哈希保存在内存中是否足够安全,以便在应用程序关闭时将其删除?

4

2 回答 2

7

您不应该使用密码的哈希值,哈希值的设计速度很快,因此(相对而言)很容易进行暴力攻击。使用像PBKDF2这样的密钥派生函数

不要使用直接从密码派生的密钥作为加密密钥。如果用户更改密码,则需要重新加密所有数据,备份将变得毫无价值。使用随机生成的加密密钥,您使用基于密码的密钥加密密钥进行加密。

我不太确定将哈希存储在钥匙串中,而不是仅仅将其保存在内存中。上次我研究这个时,解密钥匙串比较容易。每个可以读取您正在运行的应用程序内存的攻击者很可能能够窥探钥匙串访问或解密数据。只需将其保存在内存中,并确保在应用程序暂停到后台等情况下擦除内存。这显然也适用于每条解密数据。

[编辑:@JeffLockhart 澄清主加密密钥的过程] 您生成一个随机密钥来加密您的数据,我们称之为密钥 A。您可以使用SecRandomCopyBytes生成密钥 A,有关使用示例,请参阅Apple 的 CryptoExcercise。您使用密钥 A 来加密用户数据。要保存密钥 A,您必须使用第二个密钥 B 对密钥 A 进行加密。您不应该将密码直接用作密钥 B,因为快速暴力或字典攻击。因此,您可以使用 PBKDF 从密码中派生一个密钥,就像在这个 stackoverflow 答案中一样。然后,您使用密钥 B 加密密钥 A,例如使用CCCrypt. 您保存加密的密钥 A 和用于派生密钥 B 的盐。要解密,用户输入密码,您使用密码和盐派生密钥 B。您使用派生密钥 B 解密密钥 A。希望澄清。

于 2013-03-25T22:10:40.287 回答
1

你可以看看这个:

安全增量存储

他们实现了一个使用加密 SQLite 数据库的 NSIncrementalStore 子类。这是 Apple 的 SQLite Store 的直接替代品。还带有价格标签。

于 2013-04-27T09:42:42.377 回答