前言
随着官方对于用户隐私和数据使用上越来越严格,如何保护用户的信息也成为我们日常开发中需要关注的问题。下面给大家分享几个常见的点。
避免在设备上存储敏感信息
当我们需要在用户的设备上存储信息时:
注意这两类数据:* 应用的密钥等私有数据* 用户的敏感信息
不要共享未加密的敏感信息。如果需要存储,最好是先进行加密。在被破解的设备上,数据库什么的都能被读取。
当我们需要存储密钥类的数据时(例如密码管理App),用keystore或keychains的加密。
虽然说最好是不要在本地存储用户敏感信息,但有时无法避免。那我们有哪些办法能加强安全性呢?
对于小的数据,现在有官方的 EncryptedSharedPreferences 来对内容加密。使用如下:
String masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC);
SharedPreferences sharedPreferences = EncryptedSharedPreferences.create("secret_shared_prefs",masterKeyAlias,context,EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
);
// 当作普通的SP用就可以了
SharedPreferences.Editor editor = sharedPreferences.edit();
对于数据流,可以用CipherInputStream和CipherOutputStream。他们可以用来封装普通的数据流,这样加解密的过程对于使用者来说就是“隐形”的。下面看看具体的例子:
// 初始化Cipher
final Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, key);
// 封装加密数据流
OutputStream wrapped = new CipherOutputStream(out, cipher);
CipherInputStream的使用也类似。
注意系统自动备份
大家应该在manifest.xml里看到过allowBackup这个设置。它有什么作用呢?看看官方文档的原话:
是否允许应用参与备份和恢复基础架构。如果将此属性设为 false,则永远不会为该应用执行备份或恢复,即使是采用全系统备份方法也不例外(这种备份方法通常会通过 adb 保存所有应用数据)。此属性的默认值为 true。
就是说在默认情况下,应用会允许第三方将应用的词有存储进行转移。这种设计的本意可能是为了方便用户备份自己的设备。但是黑客会怎样利用这个呢?在一个解锁了的设备上,他们可以轻易地把数据从应用的私有存储复制到外面来窃取信息。
解决办法当然就是把它设为allowBackup="false"。这样可以保证用户的数据不会被转移到读取权限更低的地方。
注意:从 Android 6.0 起,allowBackup 也会影响系统自动备份功能上传数据至Google Drive(类似于 iCloud)。
如果要使用系统的自动备份功能,需要在 Google Drive 账户的fullBackupContent设置里声明可以被备份的文件列表。
使用 secure flag
不知道大家有没有注意过,有些应用当你在输入支付信息(例如银行卡号)时,没法截屏。很大可能是因为他们的应用启用了LayoutParams.FLAG_SECURE,作用就是其他应用无法对此应用截屏或录像。当这类应用显示在任务栏内时,会默认显示空白页面而不是当前内容的截图。
简单的实现如下:
class MainActivity : AppCompatActivity() {...override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE)}...
}
从Android 5.0起,第三方应用只可以收集没有这个设置的应用的内容。想象一个场景,我们在应用A输入支付信息时,切去应用B发了条消息,如果应用A没有做这个设置,某些应用就可以偷偷截屏保存我们的支付信息。当然现在很多支付都有加强的验证,比如短信验证码。但是这类信息泄漏的话,还是会让人防不胜防。
总结
虽然我们日常开发不会天天接触到这些(就像CI/CD的设置),但是当我们实现了新功能需要发布时,对信息的安全性做一些检查,既是对用户负责,说不定也给自己和公司免去一些潜在的麻烦。