我有一些代码用于加密和解密ios应用程序中的某些字符串。该代码涉及CCCrypt的使用。有没有一种可靠的方法来测试所使用的密钥的有效性而无需将密钥实际存储在任何地方?根据我的研究,似乎接近告知密钥是否有效的唯一方法是使用密钥长度和密钥哈希。任何人都可以指导我正确的方向吗?
答案 0 :(得分:6)
获得答案需要一些关于正确加密的背景知识。你可能已经知道了这一点,但是大多数人都这样做了,所以我要覆盖它。 (如果您使用密码进行加密,并且至少不编码HMAC,两种盐和IV,那么您做错了。)
首先,每次使用未经身份验证的模式(例如AES-CBC)进行加密时,都必须使用HMAC(请参阅CCHmac()
)。否则,攻击者可以修改您的密文,使其解密为不同的消息。有关此攻击的示例,请参阅modaes。 HMAC是基于密钥的加密安全散列。
其次,如果您使用的是基于密码的加密,则必须使用KDF将其转换为密钥。最常见的是PBKDF2。您不能只将密码字节复制到密钥中。
假设您以这种方式使用密码,通常会生成两个密钥,一个用于加密,一个用于HMAC。
好的,在这些部件到位后,您可以验证密码是否正确,因为如果不是,HMAC将会失败。 RNCryptor就是这样做的。
这种简单方法存在两个问题:您必须先处理整个文件,然后才能验证密码,并且无法检测文件损坏与密码错误。
要稍微解决这些问题,您可以单独添加一小部分额外数据。然后验证小块而不是整个文件。这基本上就是aescrypt的作用。具体来说,它们生成用于加密整个文件的“真实”密钥,然后分别使用PBKDF2生成的密钥和HMAC加密该密钥。某些形式的腐败仍然看起来像是不好的密码,但通过这种方式区分它们要容易一些。
答案 1 :(得分:0)
您可以在数据库中存储使用密钥加密的已知值。验证密钥是否正确是很简单的:您加密已知字符串,并将其与数据库中的加密输出进行比较。如果您坚持使用单个数据块,那么您不必担心操作模式,并且可以保持简单。
也可以存储密钥的哈希值,但我会将密钥视为密码,并采取在数据库中存储密码时采取的所有防御措施(例如使用bcrypt,盐哈希,等)。
如果你不能存储这些值,你可以解密你不知道实际内容的东西,但也许知道消息的某些属性(例如ASCII文本,今天的日期在字符串中的某个地方等)和测试这些属性的解密消息。然后,如果解密的块没有那些属性(例如,设置了MSB的字节,没有日期的实例),则表示密钥无效。在这种情况下有可能出现误报,但机会非常低。
答案 2 :(得分:0)
一般来说,我同意Peter Elliott的观点。但是,我还有几点意见:
a)如果随机生成密钥,则存储密钥的哈希是安全的
b)您始终可以附加到加密消息(如果可以控制的话)的orginial消息的散列。在这种情况下,您可以解密消息,获取解密消息的哈希值,并将其与原始消息的哈希值进行比较。如果它们是eqaul,则使用正确的密钥进行解密。