安卓:如何存储用户名和密码?

185
如果我想在Android应用程序中存储用户名和密码以供使用,最好的方法是什么?通过偏好设置屏幕吗(但如果用户错过了呢?),还是弹出对话框并要求用户输入凭据? 如果是这样,我需要为应用程序维护状态。我该如何做到这一点?

4
了解一下@RetoMeier(谷歌Android开发技术领导)对这个问题的看法。https://dev59.com/E3RA5IYBdhLWcg3w6SRH#786588 - tony gil
1
如果您正在寻找最安全的存储凭据的方法,请阅读此答案https://dev59.com/jmgu5IYBdhLWcg3w6bGo#20560574 - Durai Amuthan.H
3
@Legend,你是怎么解决你的问题的? - Erum
@Legend,你能否谈谈在加密后将密码保存在首选项中的问题。因为我希望我的应用程序可以在没有互联网的情况下工作,那么我该如何获取密钥呢?(因为我不能将密钥存储在设备上) - eRaisedToX
您可以使用密钥库来保护Api +18。https://developer.android.com/training/articles/keystore - Nabzi
9个回答

124
我看到的大多数Android和iPhone应用程序都使用初始屏幕或对话框来请求凭据。我认为用户经常重新输入他们的用户名/密码是很麻烦的,因此从可用性的角度来看,存储这些信息是有意义的。 Android dev guide中的建议是:
一般来说,我们建议最小化要求用户提供凭据的频率——这样可以使网络钓鱼攻击更加显眼,也更不可能成功。而是使用授权令牌并更新它。
在可能的情况下,不应该将用户名和密码存储在设备上。相反,使用用户提供的用户名和密码进行初始身份验证,然后使用短期的、服务特定的授权令牌。
使用AccountManger是存储凭据的最佳选择。SampleSyncAdapter提供了如何使用它的示例。
如果由于某种原因您不能使用它,则可以使用Preferences机制持久化凭据。其他应用程序无法访问您的首选项,因此用户的信息不容易被曝光。

43
将密码信息如原样持久保存在偏好设置中是有风险的。在已经获取了Root权限的手机上,可以访问应用程序的偏好设置文件。至少你可以对密码进行模糊处理。 - Jayesh
54
如果有人拿到了你的手机并且成功获取了root权限,那么你很难保护你的数据安全。虽然混淆密码是个不错的主意,但这并不能提供太多的保护。更重要的是操作系统已经内置了许多安全层级。当然,你也不想做任何愚蠢的事来规避这些措施。使用类似于OAuth的系统,并在设备上存储一个令牌而不是用户名和密码可能会更好一些。 - Eric Levine
4
如果您使用“账户管理器”(如我的回答和@Miguel间接提到的),如果有人掌握了您的GSM手机,他们需要继续使用您的SIM卡才能访问您的账户,因为当SIM卡更换时,存储的凭据将无效化。 - Jon O
3
很久以前就取消了更改SIP时的账户清除功能,因为这对于拥有多张SIM卡的人来说意义不大。如果你的手机被盗,更好的策略是前往你的Google账户页面,并撤销该特定设备的访问权限。 - Nikolay Elenkov
2
@Coder 根据我回答中提供的文档,AccountManager自API 5以来就可用。 - Eric Levine
显示剩余5条评论

9
你应该使用Android AccountManager。它专门为此场景而建立。虽然有点繁琐,但它的一项功能是在SIM卡更改时使本地凭据失效,因此如果有人偷走你的手机并将新的SIM卡插入其中,你的凭据就不会被泄露。

这还为用户提供了一个快速简便的方式来访问(并潜在地删除)设备上任何帐户的存储凭据,所有这些都可以从一个地方完成。

SampleSyncAdapter(如@Miguel所提到的)是一个利用存储的帐户凭据的示例。


3
账户管理器会在何处记录“如果 SIM 卡更换,将使本地凭据无效”的信息? - Eric Levine
我不是很清楚。然而,在一些使用我的应用程序的用户进行SIM卡更换后,他们遇到了身份验证问题,这是我开始相信/接受/理解的事情。 - Jon O
1
我在JavaDocs或AccountManager代碼中沒有找到它。這聽起來像是一個不錯的功能,只是很好驗證和理解細節。 - Eric Levine
快速测试一下,取出你的SIM卡并尝试使用存储的凭据通过wifi进行认证。我想亲自尝试一下,但我使用的是CDMA网络。 - Jon O
2
根据@NikolayElenkov的说法,SIM卡更换时的无效功能已被移除。 - ThomasW
2
@ThomasW,你有这方面的引用吗?能够得到一个明确的答案会很好。 - Jon O

8
我认为保护凭据的最佳方法是首先考虑将密码加密存储在account.db文件中,这对于非root设备不易获取,在root设备上黑客必须需要密钥才能解密。
另一种选择是像Gmail一样进行所有身份验证。在与Gmail服务器进行第一次身份验证后,您获得了Auth Token。该令牌将用于处理密码,并以明文存储。如果从服务器更改密码,则该令牌可能会失效。
我建议您启用双重身份验证并为您的设备创建特定设备密码,这是最后一个选项。在丢失设备后,您只需要禁用该设备。

2
你能否提供一个证明accounts.db被加密的来源吗?或者你是说特定的密码应该被加密? - Michał Klimczak
1
@Riz,加密密钥应该存储在哪里呢?因为我的应用程序可以在没有互联网的情况下运行,所以无法从网络获取。 - eRaisedToX

3

2
这些按照难度排序,以便窃取您的隐藏信息。
1. 明文存储 2. 使用对称密钥加密存储 3. 使用Android Keystore 4. 使用非对称密钥加密存储
来源:在Android应用程序中存储密码的最佳位置

Keystore本身使用用户自己的锁屏PIN /密码进行加密,因此,当设备屏幕被锁定时,Keystore不可用。 如果您有一个需要访问应用程序秘密的后台服务,请记住这一点。

来源:简单使用Android Keystore存储密码和其他敏感信息

2

2

使用新的(Android 6.0)指纹硬件和API,您可以像这个GitHub示例应用程序中那样进行操作。


8
参考示例项目在Android Key Store中创建一个密钥,并使用它创建一个密码器来加密密码。加密后的密码和密码器以base64编码字符串的形式存储在共享首选项中。成功进行指纹身份验证后,从Android Key Store检索秘密密钥,并与解码的密码器一起使用来解密解码的密码。 - mjwheat
@mjwheat 这真的很有帮助,让我了解了示例中正在发生的事情。谢谢!有一个小错别字:"...来解密编码密码。" - muetzenflo

2

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接