24

我正在开发一个应用程序,用户需要登录才能执行操作......但主要是在android手机上使用“保持我登录状态”...并且在这种情况下我将不得不在我的应用程序中保留用户名和密码的价值..我应该使用首选项还是SQLite Db或者是否有其他内容,如何才能使其安全? plz帮助... 在此先感谢..在Android应用程序中存储用户名和密码的最佳选择

+0

这工作正常:http://stackoverflow.com/a/19629701/5733853 – HPbyP 2016-11-22 20:14:24

回答

4

最起码,它存储在SharedPreferences(私密模式),不要忘了哈希密码。虽然这不会对恶意用户(或根源设备)产生影响,但它是某种东西。

+0

任何教程如何散列密码?我对这个想法很感兴趣。没有人可以使用该技术检索存储的密码? – androniennn 2012-02-10 19:10:03

+1

@androniennn有关于如何哈希密码教程_ton_所以我会让你谷歌。有一点需要记住的是散列只是为了阻止_casual_ snooper。这种技术**在设备植根时(例如)不起作用,并且恶意用户也可以访问您的二进制文件。想想看,如果有人能够对你的程序进行逆向工程,那么他们可以很容易地弄清楚你如何舍弃密码。你只需要知道所有的可能:) – 2012-02-10 19:14:13

+0

一个很好的方法/技术,但不是100%肯定和安全的:\ – androniennn 2012-02-11 23:58:16

25

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

我以前使用过的一种解决方案是让服务器生成一个“票据”,并将其传递回设备,这对于一段时间是有利的。这张票被设备用于所有通信,当然使用SSL,这样人们就不会偷走你的票。这样,用户在服务器上验证其密码一次,服务器发回过期的故​​障单,并且密码永远不会存储在设备上的任何位置。

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

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

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

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

+3

我同意你在技术上说的一切。但我觉得你的血型越公开,越有可能在紧急情况下可以挽救;) – 2014-01-30 17:47:44

+2

数据不是超级秘密并不重要,用户可以在许多地方使用相同的用户/密码攻击者可以获得这些服务并尝试不同的服务。 – 2016-10-12 11:30:40

22

正如其他人所说,没有安全的方式来存储在Android的密码,充分保护数据。散列/加密密码是一个好主意,但它所要做的只是减缓“破解者”。

随着中说,这是我做的:

1)我用这个simplecryto.java class这需要一个种子和一个文本和加密。 2)我使用私人模式下的SharedPreferences,它保护非根设备中保存的文件。 3)我用于simplecryto的种子是一个比字符串更难找到的字节数组。

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

请记住,“破解者”将需要物理访问设备,并根据它并谨慎地找到种子。

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

+0

教程链接已损坏,所以我不确定它是否相同,但Google立即给了我一篇看起来很相似的文章:http://www.androidsnippets.com/encryptdecrypt-strings,但它发生了对我来说,你可以使用一个随机生成的种子存储在设备上以增加安全性。这个共享的秘密/种子将是每个用户随机生成的,并且脱离设备的存储将包含该映射。只要您安全地与该位置安全地交换信息,并且该存储是安全的,那么效果会不会更好? – batbrat 2014-03-11 09:29:49

+1

@batbrat如果你要有一个服务器端持久用户状态,推荐oauth2而不是自己研发的东西。在我的例子中,没有用户状态,所以我没有任何可用的对象。 – knaak 2014-03-11 19:17:00

+0

谢谢您澄清。我现在明白了,并且同意。 – batbrat 2014-03-11 19:35:06

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(); 
      } 
+1

欢迎来到StackOverflow!您是否也可以提供解释来帮助PO了解您的答案? – FrankS101 2016-09-01 11:30:55

+6

Base64不加密,它是编码算法,非常容易识别和解码。 – 2016-10-27 12:56:09

0

使用NDK进行加密和解密与定义字符串键变了,而不是将其保存在共享偏好或定义它沿着INS字符串XML将有助于防止对大多数脚本小子的密钥窃取。结果密文将被存储在共享首选项中。 This link may help about the sample code

相关问题