我正在开发一款基于网络服务器的Android应用。安装该应用程序的用户应该在网上注册,以便他们可以登录。当有人尝试登录时,我会使用API
验证其信息。
所以我对持久化和加密过程感到好奇。我应该加密值还是只将它们全部放到SharedPreferences
?如果需要加密,那么有效的方式是什么?
最后但并非最不重要的是,SharedPreferences在安全方面是否足够?
感谢。
答案 0 :(得分:3)
加密很容易,但真正的问题是用什么键?如果您在应用程序中对密钥进行硬编码,或从某个已知值导出密钥,则任何有权访问该设备的人都可以轻松解密这些值。你所取得的成就仅仅是混淆。由于Android没有系统密钥库的公共API,因此如果您需要保存实际密码,则无法执行其他操作。除非你每次启动应用程序时都让用户输入密码,否则会破坏目的。
如果您同时控制服务器和客户端,则另一种方法是使用某种形式的基于令牌的身份验证,并仅保存令牌。由于令牌可能会过期并被撤销,因此获取令牌的人所造成的损害要远远少于暴露实际密码(也可能在其他网站上使用)。
答案 1 :(得分:2)
当然,您应该加密用户设置,如登录,密码或电子邮件。我更喜欢SharedPreferences
进行存储,是的,这在安全性方面已经足够了。
我在StackOverflow上找到了这两个方法,这很公平:
protected String encrypt( String value ) {
try {
final byte[] bytes = value!=null ? value.getBytes(UTF8) : new byte[0];
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey key = keyFactory.generateSecret(new PBEKeySpec(SEKRIT));
Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(Settings.Secure.getString(context.getContentResolver(),Settings.System.ANDROID_ID).getBytes(UTF8), 20));
return new String(Base64.encode(pbeCipher.doFinal(bytes), Base64.NO_WRAP),UTF8);
} catch( Exception e ) {
throw new RuntimeException(e);
}
}
protected String decrypt(String value){
try {
final byte[] bytes = value!=null ? Base64.decode(value,Base64.DEFAULT) : new byte[0];
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey key = keyFactory.generateSecret(new PBEKeySpec(SEKRIT));
Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
pbeCipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(Settings.Secure.getString(context.getContentResolver(),Settings.System.ANDROID_ID).getBytes(UTF8), 20));
return new String(pbeCipher.doFinal(bytes),UTF8);
} catch( Exception e) {
throw new RuntimeException(e);
}
}
找不到链接,如果我发现,我会编辑我的答案。
修改:我找到了来源,您可以查看有关here的所有讨论。
答案 2 :(得分:2)