安全地在Android设备中存储AES密钥
问题描述:
我想加密用户指定的字符串列表。用于加密和解密此数据的AES密钥必须保存在设备上,以便用户每次需要时都可以使用它解密数据。我已经读过使用Keystore是存储密钥的一个很好的选择,但是我已阅读的大多数指南都将它与签名应用程序相关联,这不完全是我想要的。我的应用程序要求用户输入一个密码,然后使用用密码解锁的密钥解密字符串数据。我该怎么做呢?安全地在Android设备中存储AES密钥
谢谢。
答
它很难回答你的问题,而没有你以一种确切的方式“安全地”定义。你在谈论其他应用程序的安全性吗?针对其他用户的安全?安全防盗设备?或防止损失的安全?
另外,你在说什么安全级别?数据在给定密钥下的加密是否足够敏感,以便能够认真考虑密钥的存储方式?
据我的理解,如果数据具有高度敏感性,您应该使用基于密码的密钥派生函数(如PBKDF#2,Bcrypt或Scrypt)直接从密码派生密钥。通过这种方式,关键材料不需要直接存储在设备上。
如果您打算无论出于何种原因存储主加密密钥,请使用密码密钥进行加密,并在SharedPreferences下将其存储为Base64字符串,并使用MODE_PRIVATE
来保护它免受其他应用程序的侵害。即使密钥被恶意用户/设备盗用,但没有正确的密码密钥,密钥材料本身也是无用的。
如果您想防止丢失密钥,则不应将密钥存储在设备上,而应存储在您自己的服务器上,并再次使用密码密钥进行加密,这样数据库的妥协也不会导致数据泄露。
总之,我建议你尽量不要将任何种类的私钥存储到设备本身,而是使用密码派生密钥作为所有密码操作的主密钥。保留在公钥加密和已知公钥证书中生成的私钥的密钥库。
我以前试过PBKDF2,但每次都会生成不同的密钥,即使密码是相同的。 – sm123 2015-02-08 20:23:42
另外,即使我要生成每次必须相同的PBKDF2密钥,我是否也不需要对盐进行硬编码,这可能会被攻击者检索到? – sm123 2015-02-08 20:43:32
@ gl321第一次随机生成salt并将其存储在共享首选项中。算法的salt和参数不是私有的,因为攻击者可以在没有任何安全风险的情况下检索它们,只要确保每个用户的salt是随机的(禁止为所有用户生成彩虹表)。一旦生成了初始密钥,确保盐不会丢失(也可能存储在您自己的服务器上)。编码密钥可以在用户下次登录时定期更改,并生成新的盐。 – initramfs 2015-02-09 03:52:33