核心数据加密 [英] Core Data Encryption

查看:185
本文介绍了核心数据加密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



在我的Core Data数据库中,我有一个特殊的实体,它有一个随机数!= 0这只是价值。要测试用户是否输入了正确的密码,我取得该实体并读取该号码。如果是=! 0,我知道密码是正确的,因为解密失败NSValueTransformer总是返回0。



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



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

解决方案

你不应该使用哈希的密码,哈希的设计是快速的,所以(相对)容易做暴力攻击。使用关键派生功能,如 PBKDF2



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



我不太确定将密钥存储在钥匙串中而不是只是拿着它在记忆中最后一次我研究了这个,它比较容易解密钥匙串。并且每个可以读取正在运行的应用程序的内存的攻击者最有可能能够窥探钥匙串访问或解密的数据。只需将其保存在内存中,并确保在应用程序挂起后台时擦拭内存。这对每一个解密的数据显然也是如此。




你生成一个随机密钥加密你的数据,让我们称之为关键A.你可以使用 SecRandomCopyBytes 生成密钥A,请参见 Apple的CryptoExcercise 的一个用法示例。您使用密钥A来加密用户数据。要保存密钥A,您必须使用第二个密钥B对密钥A进行加密。不要使用密码直接作为密钥B,因为强烈的强力或字典攻击。因此,您可以使用PBKDF从密码中获取密钥,例如
stackoverflow答案。然后用密钥B对密钥A进行加密,例如使用 CCCrypt 。保存加密密钥A和用于导出密钥B的盐。
要解密,用户输入密码,您使用密码和salt导出密钥B。您使用派生密钥B解密密钥A.希望澄清。


I have a question about Core Data encryption. I'm storing some sensitive user data in a Core Data SQLite database. The critical values are all transformables and I'm using AES256 to encrypt and decrypt them 'on the fly', including an individual IV for every value. The encryption key is the SHA512 hash of the password the user has chosen. This works very well so far.

Now about the user password. When the user launches the app he is asked for his password. The password is being hashed with SHA512 and stored in the iOS keychain. For every write or read operation the NSValueTransformer will get the password from the keychain. If the app is being closed, I delete the password hash from the keychain.

In my Core Data database I have a special entity which has a random number != 0 as it's only value. To test if the user has entered the correct password I fetch this entity and read the number. If it is =! 0, I know that the password was correct because when the decryption fails the NSValueTransformer always returns 0.

Now my actual questions: Would you consider this a good approach on encryption? How else would you test if the entered password is correct?

I'm a little concerned that storing the password hash in the keychain while the app is running makes everything slower, because the NSValueTransformer has to access the keychain all the time. Would it be sufficiently secure to just keep the password hash in memory, so it'll be deleted when the app closes?

解决方案

You shouldn't use the hash of the password, hashes are designed to be fast so it's (comparatively) easy to do a brute-force attack. Use a key derivation function like PBKDF2.

Don't use a key directly derived from the password as an encryption key. If the user changes the password, you need to reencrypt all data and backups become worthless. Use a randomly generated encryption key that you encrypt with a key encryption key based on the password.

I'm not so sure about storing the hash in the keychain instead of just holding it in memory. The last time I looked into this, it was comparetively easy to decrypt the keychain. And every attacker that can read the memory of your running app will most likely be able to snoop on the keychain access or the decrypted data. Just keep it in memory and make sure to wipe the memory if the app suspends into background etc. This holds obviously also true for every piece of decrypted data.

[EDIT: @JeffLockhart to clarify the procedure for a master encryption key] you generate a random key to encrypt your data, let's call it key A. You could use SecRandomCopyBytes to generate key A, see Apple's CryptoExcercise for a usage example. You use key A to encrypt the user data. To save key A, you have to encrypt key A with a second key B. You shouldn't use the password directly as key B, because of fast brute-force or dictionary attacks. So you derive a key from the password with a PBKDF, like in this stackoverflow answer. You then encrypt key A with key B, e.g. using CCCrypt. You save the encrypted key A and the salt used to derive key B it. To decrypt, the user enters the password, you derive key B using the password and the salt. You decrypt key A using the derived key B. Hope that clarifies.

这篇关于核心数据加密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆