我对Core Data加密有疑问。我将一些敏感的用户数据存储在Core Data SQLite数据库中。关键值都是可转换的,我正在使用AES256来“加速”加密和解密它们,包括每个值的单个IV。加密密钥是用户选择的密码的SHA512哈希值。到目前为止,这种方法非常有效。
现在关于用户密码。当用户启动应用程序时,系统会要求他输入密码。密码使用SHA512进行哈希处理并存储在iOS钥匙串中。对于每次写入或读取操作,NSValueTransformer将从钥匙串获取密码。如果应用程序正在关闭,我会从钥匙串中删除密码哈希。
在我的核心数据库中,我有一个特殊的实体,它有一个随机数!= 0,因为它是唯一的值。要测试用户是否输入了正确的密码,我会获取此实体并读取该数字。如果是=! 0,我知道密码是正确的,因为当解密失败时,NSValueTransformer总是返回0.
现在我的实际问题:您认为这是一种加密的好方法吗?如果输入的密码正确,您还要怎么测试?
我有点担心在应用程序运行时将密码哈希存储在钥匙串中会使一切变慢,因为NSValueTransformer必须始终访问钥匙串。将密码哈希保存在内存中是否足够安全,因此当应用程序关闭时它将被删除?
答案 0 :(得分:7)
你不应该使用密码的哈希值,哈希设计得很快,因此(相对)容易进行暴力攻击。使用key derivation function之类的PBKDF2。
请勿使用直接从密码派生的密钥作为加密密钥。如果用户更改密码,则需要重新加密所有数据,备份变得毫无价值。使用随机生成的加密密钥,使用基于密码的密钥加密密钥加密。
我不太确定将哈希存储在钥匙串中而不是仅仅将其保存在内存中。我最后一次研究这个,解密钥匙链比较容易。每个能够读取正在运行的应用程序内存的攻击者都很可能能够窥探密钥链访问或解密数据。只需将其保留在内存中,并确保在应用程序暂停到后台等时擦除内存。对于每一段解密数据,这显然也适用。
[编辑:@JeffLockhart澄清主加密密钥的过程] 您生成一个随机密钥来加密您的数据,我们称之为密钥A.您可以使用SecRandomCopyBytes生成密钥A,有关用法示例,请参阅Apple's CryptoExcercise。您使用密钥A加密用户数据。要保存密钥A,您必须使用第二个密钥B加密密钥A.由于快速暴力破解或字典攻击,您不应将密码直接用作密钥B.因此,您可以使用PBKDF从密码中获取密钥,例如this stackoverflow的答案。然后,您使用密钥B加密密钥A,例如,使用CCCrypt。您保存加密密钥A和用于派生密钥B的盐。 要解密,用户输入密码,您使用密码和salt派生密钥B.您使用派生密钥B解密密钥A.希望澄清。
答案 1 :(得分:1)
你可以看看这个:
他们已经实现了一个使用加密的SQLite-Database的NSIncrementalStore子类。这是Apple的SQLite商店的直接替代品。还带有价格标签。