在Android应用程序中存储用户名和密码的最佳选择

问题描述 投票:33回答:6

我正在开发一个应用程序,用户需要登录才能执行操作...但主要是在Android手机上使用“让我登录”......在这种情况下我将不得不维护用户名和密码的值我的应用程序..应该使用首选项,还是SQLite Db,还是有其他东西,我怎样才能使它安全? Plz帮助...在此先感谢..

android sharedpreferences android-preferences sqliteopenhelper
6个回答
28
投票

是的,这在Android上很棘手。您不希望将明文密码存储在首选项中,因为拥有root设备的任何人都将基本上向世界显示其密码。另一方面,您不能使用加密密码,因为您必须将加密/解密密钥存储在设备的某个位置,再次容易受到根攻击。

我曾经使用的一个解决方案是让服务器生成一个“票据”,然后将其传递回设备,这在一段时间内是有益的。该票据由设备用于所有通信,当然使用SSL,因此人们无法窃取您的票。这样,用户在服务器上验证一次密码,服务器发回一张过期的票证,密码永远不会存储在设备上的任何地方。

几个三脚认证机制,如OpenID,Facebook,甚至谷歌API,都使用这种机制。缺点是每隔一段时间,当票证到期时,用户需要重新登录。

最终,它取决于您希望应用程序的安全性。如果这只是为了区分用户,并且没有像银行账户或血型那样存储超级机密信息,那么也许在设备上以明文方式保存pwd就可以了:)

祝你好运,无论你决定哪种方法最适合你的特殊情况!

编辑:我应该注意,这种技术将安全责任转移到服务器 - 您将希望使用盐水哈希在服务器上进行密码比较,这个想法你会在这个问题的其他一些评论中看到。这可以防止明文密码出现在除设备上的EditText View,服务器的SSL通信以及服务器的RAM(除盐和哈希密码)之外的任何地方。它永远不会存储在磁盘上,这是一件好事(tm)。


24
投票

正如其他人所说,没有安全的方法可以在Android中存储密码,从而完全保护数据。散列/加密密码是个好主意,但它只会减慢“破解者”的速度。

话虽如此,这就是我所做的:

1)我使用这个simplecryto.java class,它接受种子和文本并加密它。 2)我在私有模式下使用SharedPreferences,它保护非root设备中保存的文件。 3)我用于simplecryto的种子是一个字节数组,反编译器比String更难找到。

我的申请最近由我公司聘请的“白帽”安全小组审核。他们标记了这个问题,并表示我应该使用OAUTH,但他们也将其列为低风险问题,这意味着它不是很好,但还不足以阻止发布。

请记住,“破解者”需要对设备进行物理访问并对其进行根处并且足够小心地找到种子。

如果您真的关心安全性,请不要“保持登录状态”选项。


6
投票

至少,将它存储在SharedPreferences(私有模式)中,不要忘记哈希密码。虽然这对恶意用户(或有根设备)没有什么影响,但它确实存在。


1
投票

在不危及安全性的情况下,最安全的方法是使用共享首选项来存储最后一个登录用户的用户名。

此外,在您的用户表中,引入一个包含数字布尔值(1或0)的列来表示该人是否选中了该人选中了“记住我”复选框。

启动应用程序时,使用getSharedPreferences()函数获取用户名,并使用它来查询托管数据库,以查看signedin列是1还是0,其中1表示此人选中了“记住我”复选框。


1
投票
 //encode password
 pass_word_et = (EditText) v.findViewById(R.id.password_et);
 String pwd = pass_word_et.getText().toString();
                byte[] data = new byte[0];
                try {
                    data = pwd.getBytes("UTF-8");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                String base64 = Base64.encodeToString(data, Base64.DEFAULT);
                hbha_pref_helper.saveStringValue("pass_word", base64);

 //decode password
 String base64=hbha_pref_helper.getStringValue("pass_word");
            byte[] data = Base64.decode(base64, Base64.DEFAULT);
            String decrypt_pwd="";
            try {
                 decrypt_pwd = new String(data, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

0
投票

使用NDK进行加密和解密以及定义String Key变量,而不是将其保存在共享首选项中或定义它,而字符串xml将有助于防止秘密密钥窃取大多数脚本小子。然后,生成的密文将存储在共享首选项中。 This link may help about the sample code

© www.soinside.com 2019 - 2024. All rights reserved.