核心数据encryption

我有一个关于核心数据encryption的问题。 我在Core Data SQLite数据库中存储了一些敏感的用户数据。 临界值都是可变换的,我正在使用AES256对它们进行encryption和解密,包括每个值的个人IV。 encryption密钥是用户select的密码的SHA512散列。 迄今为止,这工作得很好。

现在关于用户密码。 当用户启动应用程序时,他被要求input密码。 密码正在用SHA512散列并存储在iOS钥匙串中。 对于每个写入或读取操作,NSValueTransformer将从钥匙串获取密码。 如果应用程序正在closures,我将从密钥链中删除密码哈希。

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

现在我的实际问题:你认为这是一个很好的encryption方法? 如果input的密码是正确的,你还会怎么testing?

我有点担心在应用程序运行时将密码哈希存储在钥匙串中会使得一切都变慢,因为NSValueTransformer必须始终访问钥匙串。 将密码散列保存在内存中是否足够安全,所以应用程序closures时会被删除?

你不应该使用密码哈希,哈希被devise为快速,所以它(相对)容易做一个暴力攻击。 使用像PBKDF2这样的密钥派生函数 。

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

我不太确定将哈希存储在钥匙串中,而不是将其保存在内存中。 我最后一次研究这个问题时,解密钥匙链是比较容易的。 而且每个能够读取正在运行的应用程序的内存的攻击者很可能能够窥探钥匙串访问或解密的数据。 只要将它保存在内存中,并确保如果应用程序挂起到背景等擦拭内存。这显然也适用于每一个解密的数据。

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

你可以看看这个:

安全增量存储

他们实现了一个使用encryption的SQLite数据库的NSIncrementalStore子类。 这是苹果的SQLite商店的一个替代品。 还有一个价格标签。