Java 在安卓设备中安全存储AES密钥

Java 在安卓设备中安全存储AES密钥,java,android,encryption,cryptography,Java,Android,Encryption,Cryptography,我正在尝试加密用户指定的字符串列表。用于加密和解密此数据的AES密钥必须保存在设备上,以便在用户需要时可用于解密数据。我已经读到使用Keystore存储密钥是一个很好的选择,但是我读到的大多数指南都将其与签名应用程序相关,这并不是我想要的。我的应用程序要求用户输入密码,然后使用密码解锁的密钥解密字符串数据。我该怎么做 谢谢。如果你不准确地定义“安全”,很难回答你的问题。你说的是针对其他应用程序的安全性吗?针对其他用户的安全性?设备防盗安全?还是损失担保 另外,你说的是什么级别的安全?在给定密钥下

我正在尝试加密用户指定的字符串列表。用于加密和解密此数据的AES密钥必须保存在设备上,以便在用户需要时可用于解密数据。我已经读到使用Keystore存储密钥是一个很好的选择,但是我读到的大多数指南都将其与签名应用程序相关,这并不是我想要的。我的应用程序要求用户输入密码,然后使用密码解锁的密钥解密字符串数据。我该怎么做


谢谢。

如果你不准确地定义“安全”,很难回答你的问题。你说的是针对其他应用程序的安全性吗?针对其他用户的安全性?设备防盗安全?还是损失担保

另外,你说的是什么级别的安全?在给定密钥下加密的数据是否足够敏感,以至于需要认真考虑密钥的存储方式

据我所知,如果数据具有高度敏感性,则应使用基于密码的密钥派生函数(如PBKDF#2、Bcrypt或Scrypt)直接从密码派生密钥。这样,关键材料就不需要直接存储在设备上

如果出于任何原因您打算存储主加密密钥,请在密码密钥下加密,并使用
MODE\u PRIVATE
将其存储为SharedReferences下的Base64字符串,以防其他应用程序攻击它。即使密钥是由恶意用户/设备盗窃恢复的,但没有正确的密码密钥,密钥材料本身也是无用的

如果您想保护密钥不丢失,则不应将密钥存储在设备上,而应存储在您自己的服务器上,再次使用密码密钥进行加密,这样数据库泄露也不会导致数据泄露


总之,我建议您尽量不要将任何类型的私钥存储到设备本身,而是使用密码派生密钥作为所有加密操作的主密钥。保留公钥加密和已知公钥证书中生成的私钥的密钥库。

我以前尝试过PBKDF2,但每次都生成不同的密钥,即使密码相同。此外,即使我要生成每次都必须相同的PBKDF2密钥,难道我不需要硬编码salt,攻击者可以检索到它吗?@gl321在第一次随机生成salt并将其存储在共享首选项中。该算法的salt和参数不是私有的,因为攻击者可以在没有任何安全风险的情况下检索它们,只需确保salt是每个用户随机的(禁止为所有用户生成彩虹表)。生成初始密钥后,确保salt没有丢失(可能也存储在您自己的服务器上)。编码密钥可以在用户下次登录时定期更改,并生成新的salt。我相信如果密钥更改,我必须解密并重新加密字符串。有什么解决办法吗?此外,IV参数是否也应硬编码?非常感谢您的帮助。@gl321不要硬编码任何内容。让它们在需要时随机生成,然后存储。如果将相同的(生成的)种子与PBKDF#2/Bcrypt或Scrypt一起使用,则会得到相同的密钥。如果出于任何原因确实需要更改密钥,则需要对所有内容进行解密,然后重新加密,这是无法避免的。我建议仅在用户的大部分数据已经解密时执行密钥更改,您只需要对数据进行适当的加密。如果不知道系统任务的确切性质,就很难衡量系统的需求。