1

我正在构建一个应用程序,它将使用 AES/CBC/PKCS5Padding 方法来加密用户设备上的数据,安全性非常重要。我想防止暴力攻击,以防有人掌握数据库。

表中的每一行都有一个关联的标题。我不知道用什么作为种子。我可以执行以下操作之一:

  1. 在源代码中硬编码我自己的种子,但我相信如果有人反编译我的应用程序,可以阅读

  2. 使用用户输入的标题作为种子

  3. 使用我自己的种子和输入的标题的串联

除非有其他方法,否则在上述所有场景中,我可以想象有人找出种子。这对他们能够暴力破解加密数据有用吗?当然,在上述所有场景中,我还将用户密码作为密钥的一部分。

我怎样才能让潜在的黑客变得更加困难?

编辑(重新编辑)

基于以下回复以及我的研究和思考过程。我想我可以做到以下几点。

  1. 让用户输入密码,但不将其存储在数据库中
  2. 在存储敏感数据之前,他们必须输入一个标签来识别它。我会将其作为明文存储在数据库中并将其用作盐
  3. 我将使用用户的密码和带有 PBKDF2 的标签来生成密钥,但不会存储它
  4. 我将使用 #3 生成的密钥来加密敏感数据
  5. 为了解密,我将再次根据用户的密码和行标签生成密钥,并使用它来解密敏感数据

这听起来对吗?如果黑客通过两列(标签明文和加密数据)掌握数据库,他们是否能够推断出任何东西?

编辑 2

我正计划构建一个具体的 Android 应用程序,以下链接非常符合我的需要。

https://nelenkov.blogspot.in/2012/04/using-password-based-encryption-on.html?m=1

https://android-developers.googleblog.com/2013/02/using-cryptography-to-store-credentials.html?m=1

4

2 回答 2

2

这里的问题是,每当有人反编译您的应用程序时,生成您的密钥的方法是众所周知的。因此,如果该密钥生成的所有输入数据都是已知的,则生成密钥是微不足道的。

因此,您可能希望为用户提供输入将与 AES 加密一起使用的密码的可能性。确保您使用诸如PBKDF2之类的系统,以防止暴力破解密码短语。

如果您的数据库不是存储在用户的设备上,而是存储在外部,那么您可能会在设备上生成和存储一个安全的随机密钥,并在数据实际存储到中央数据库之前对其进行加密。

于 2017-05-30T08:17:32.220 回答
1

根据我的评论和您的编辑,一个可能的解决方案归结为这一点(我不是真正的 Java 程序员,但下面的伪代码应该很清楚):

aesKey <- PBKDF2-SHA512(userPassword)[:32]
hmacKey <- PBKDF2-SHA512(userPassword)[32:] // PBKDF2-SHA512 has a natural 64 byte output

iv <- CSPRNG(16) // 16 byte IV for AES from a CSPRNG
ciphertext <- AES256CBC(plainText, aesKey, iv) // Use PKCS5Padding

result <- iv + ciphertext // Prepend the IV.
result <- HMAC-SHA256(result, hmacKey) + result
// Prepend the HMAC of the IV and ciphertext using the hmacKey.  Always encrypt THEN mac.

几个重要的注意事项:

  • 您应该始终在 HMAC 中包含 IV,例如,不要仅将 HMAC 包含在密文中。

  • SHA512 和 SHA256 的选择很重要。由于 SHA512 具有 64 字节的自然输出,因此非常适合使用 PBKDF2 导出两个 32 字节的密钥。如果您调整此算法,那么您将不仅仅使用最终的 PBKDF2 迭代来生成下一批字节,这是没有好处的。

  • 您用于 PBKDF2 的盐实际上并不那么重要。您可以随机生成它并将其与密文一起存储,但是,在这种情况下,PBKDF2 的静态盐就可以了。

于 2017-05-31T00:02:18.553 回答