Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在设备上存储所有数据时创建强密码方案_Java_Android_Encryption_Password Protection - Fatal编程技术网

Java 在设备上存储所有数据时创建强密码方案

Java 在设备上存储所有数据时创建强密码方案,java,android,encryption,password-protection,Java,Android,Encryption,Password Protection,背景: 我一直在开发一个Android应用程序,它将数据存储在本地数据库中,作为我最喜欢的项目。最近,我决定对应用程序进行密码保护,并对数据库进行加密。现在,我意识到动态加密数据库的复杂性,并且(考虑到我的应用程序的预期使用模式)决定只加密整个数据库文件,而不是尝试存储加密的列值等。到目前为止,我已经实现了一个系统,在每次启动应用程序时,或当用户离开我的活动时,都会提示输入密码(以说明用户按home键时,应用程序没有及时被终止) 目前,我正试图决定如何准确地对密码进行哈希运算,并将其存储在何处。

背景:
我一直在开发一个Android应用程序,它将数据存储在本地数据库中,作为我最喜欢的项目。最近,我决定对应用程序进行密码保护,并对数据库进行加密。现在,我意识到动态加密数据库的复杂性,并且(考虑到我的应用程序的预期使用模式)决定只加密整个数据库文件,而不是尝试存储加密的列值等。到目前为止,我已经实现了一个系统,在每次启动应用程序时,或当用户离开我的活动时,都会提示输入密码(以说明用户按home键时,应用程序没有及时被终止)

目前,我正试图决定如何准确地对密码进行哈希运算,并将其存储在何处。考虑到所有东西都必须存储在设备上,我基本上认为密码散列和salt已经被破坏了,因为任何花了10分钟阅读的人都可以在给定的设备上建立根目录并访问我的数据库/首选项

鉴于上述假设,我已开发出我认为仍应提供非常强大安全性的产品。我想从社区得到一些反馈,看看我的解决方案是否可行,或者是否有更好的方法

我的想法是在应用程序第一次运行时生成10个不同的随机盐值。这些值将与实际的最终密码哈希一起存储在应用程序首选项中(而不是数据库中)。请注意,只有一个密码,用于用户身份验证和数据库解密。每当出现质询时,密码将按如下方式散列:

  • 明文密码是散列的
  • 哈希密码通过与标准UPC条形码相同的校验和算法运行。这将导致值介于0和9之间(包括0和9)
  • 此校验和数字将用作salt值数组的索引。此单个salt值将追加到当前哈希
  • 然后将对新的hash+salt值进行散列,并重复步骤2-3
  • 我认为这一过程进行5次迭代就可以得到5^10种不同的盐的组合,这使得任何类型的彩虹攻击实际上都是不可能的。一旦最后的散列被验证正确,就可以使用它来解密数据库

    现在,我意识到对于一个简单的手机应用来说,这听起来有点过头了。它是。但是,这是我最喜欢的项目,为什么不呢

    问题:
    那么,在那堵文本墙之后,这种方法是合理的还是有更好的方法?我想,有了这一点,最薄弱的环节将是内存攻击,还是我错了?非常感谢您的反馈

    先谢谢你


    -干杯

    我要做的是使用数据库行的记录ID作为salt。您可以散列行的id,并将其用于zestier盐


    如果你只有十几个密码,那么它的安全性似乎与你已经在做的差不多。但是如果你有成百上千个,那么为每个ID计算一个字典表是不可行的。

    我不明白。如果要加密数据库,为什么需要在任何地方存储密码哈希

    使用PBKDF2之类的东西,从存储在用户大脑中的密码中获取加密密钥。使用它来加密数据库

    当用户想要解密数据库时,提示他们输入密码。再次从中派生密钥,并解密数据库

    存储密码哈希以进行身份验证。但这是加密,不是身份验证


    假设您有一个哈希函数,该函数以salt、迭代次数和密码作为输入,并返回一个哈希作为输出:
    byte[]hash(byte[]salt、int count、char[]password)
    。在第一次运行应用程序时随机生成一个salt,并对新选择的密码进行哈希运算。将此salt和生成的哈希存储在应用程序首选项中。然后随机生成另一个salt,并用它散列密码。将生成的哈希用作数据库加密密钥,但仅将新的salt存储在应用程序首选项中

    稍后,当用户希望使用该应用程序时,提示输入密码,并使用第一个salt对其进行哈希运算。如果它与存储的哈希匹配,则用户已证明他们知道解密密码。使用第二个salt再次对其进行哈希,并使用生成的密钥对数据库进行解密


    加密密钥的后续派生可能就是您的意思;我试图明确这一步,以防您打算将密码直接用作加密密钥。使用两种不同的密码,一种用于身份验证,另一种用于加密,将允许您安全地将相同的密码用于两种目的。

    好的。。。假设您的散列方法不弱,那么salt是否已知并不重要-salt只是让两个具有相同密码的用户具有不同的散列-并且对散列的偶然检查不会导致相同的密码显而易见。每个用户的Salt应该是唯一的

    假设(恶意)用户有root用户,除了加密之外,你绝对无法阻止他们破坏你的应用程序-特别是用户理论上可以获取你的二进制文件,对其进行反编译以确定它如何验证用户,绕过它,然后只需遵循解密机制-并且由于加密密钥在您的场景中与用户PW无关,它必须存储在某个地方-如果应用程序可以读取它,那么root也可以

    唯一真正安全的方法是使用与DB加密密钥相关的单个用户(或至少单个密码)

    除此之外,你所能期望的最好方法就是让恶意用户很难做到不值得他们这么做