Where is the best place to store a password in your Android app

[ 译文原文:Where is the best place to store a password in your Android app ]

通常Android安全问题分为几个主要类别。首先,个人信息在电话上不安全地存储,其次,与任何后台数据库或Web服务器的不安全的通信。虽然还有很多其他的事情可能出错,但大多数安全问题都属于这两个方面。在这篇文章中,我们将介绍一些应用程序中保护个人信息的各种选项。

最好的选择是永远不要在手机上存储用户的个人信息,如密码或信用卡号码。如果让用户每次都输入密码不满足您的需求,那么您将不得不在设备上的某个地方存储用户名和密码。然而在Android设备上真的没有很多地方可以存储信息。通常来说都是将information存储在shared preferences中,或在sqlite database中或设备的密钥库(keystore)中存储。

在过去几年中,我经历了手动审核几百个Android应用程序的过程,在那段时间里,我看到了一些同样的安全问题,来来回回都是。尽管我们尽最大努力让开发者了解其应用程序的安全性问题,但是似乎在攻击应用程序方面,我们取得的成功更多,而不是让任何人可以拥有解决这些问题的办法。所以为了传播知识,让我们来看看一些真实世界中,开发人员试图隐藏密码信息的认证模式。

通过破解的难易顺序有一下排行:

  1. 存储在明文
  2. 使用对称密钥存储加密
  3. 使用AndroidKeystore
  4. 使用非对称密钥存储加密

明文

使用明文意味着对用户的运行时数据没有保护 - 假设黑客具有对手机的物理访问,这是一个很大的假设。但是,您必须假设您的应用程序迟早会在二手设备上结束。您可以访问应用程序的数据文件夹中的所有信息:

命令
adb backup

然后使用Android Backup Extractor或abe.jar将其转换为tar格式。例如:

adb backup com.packagename.android
java -jar abe.jar unpack backup.ab
tar -xvf backup.tar

大量应用程序使用的一个更好的选择是在AndroidManifest.xml中将android:allowBackup标志设置为false,然后将数据保存到shared preferences或者sqlite database。这个idea的想法是,如果没有人可以备份,那么没有人能够访问存储的密码。不幸的是,这个想法有很大的缺陷。如果手机在经过二手转售时没有被正确擦除,就可以root手机,并且通过更改File的权限,然后使用adb pull命令来恢复App用户的任何动态数据(比如用户名和密码),即使不能使用adb backup命令。以下是使用公开密码的shared preferences file示例:

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="password">2secret4me</string>
<boolean name="remember" value="true" />
<string name="username">androidauthority</string>
</map>

对称加密

比较明文存储的方式,一个更好的主意是在您保存密码之前加密密码。如果您要采取这种方法,那么不要将密钥存储在APK代码或手机中的其他任何地方。使用AES,DES或任何其他对称加密算法,如果将密钥存储在可以轻松找到的地方,这就相当于形同虚设。因为找到APK是一个比较简单的过程,接下来我们获取其备份副本。

在手机上获取APK的列表

adb shell pm list packages

找到APK在手机上的位置

adb shell pm path com.packagename.android

然后使用以下命令获取APK的副本

adb pull /data/app/com.packagename.android-1/base.apk

在适当的情况下对包名称和路径或apk名称进行适当的更改。

jadx base.apk

最后将代码反编译回java源代码,看看是否可以在代码中找到加密密钥。

如果您熟悉dex2jar,那么我建议切换到jadx。反编译比dex2jar好一个数量级。我以前用dex2jar审核过的许多应用程序,后来换了使用jadx后,他们丢失了他们的secrets。

在查找密钥的时候,我们可以利用开发人员的一些习惯,他们经常把加密密钥放在很容易找到像com.packagename.android.util.security这样的地方。如果没有代码没有模糊化,而且您可以尝试搜索“加密”或“解密”等类名称或短语。想要要解密密码,将解密代码剪切并粘贴到java文件中,并将密码作为参数。
还有一些开发人员通过将包括AndroidID等设备信息以及制作和建模信息来使加密密钥具体化,但是如果您已经可以看到密钥在代码中的组合方式,这几乎是没有价值的。

AndroidKeystore

用于加密密码的最安全的选择是使用非对称加密算法,例如RSA。不对称意味着密钥分为公钥和私钥,只有私钥可以解密信息。我们看到更多的开发人员使用AndroidKeystore来存储公共和私人非对称密钥信息。
在AndroidKeystore中,这种公钥 - 私钥交换发生在设备上,似乎符合HIPAA标准。我们使用“似乎”这个词,是因为如果手机被root之后,您可以访问私钥。所以,没有什么是100%的安全,迟早有人会找到一种方法来获得钥匙,特别是如果你把所有东西放在同一个地方。

Android Keystore公钥和私钥都存储在:/data/misc/keystore/user_0 目录,私钥存储在具有<app_id>_USRCERT_<key_alias>的文件中。在有根手机上,您可以将文件复制到另一个<app_id_malicious>_USRCERT_<key_alias>,然后从你的恶意应用程序导入,您就可以恢复被加密过的密码数据。

[非译文] - 貌似Android现在可以提供硬件支持级别的密钥存储,这保证了即使系统或根应用程序也无法提取获得密钥。而针对物理访问攻击的保护是基于TrustZone实现的,低级别RSA算法的key store用于管理密钥是可行的,这使得应用程序可以使用Android内置的JCE,来提供应用程序未提供的加密算法。

[非译文] - 然而根据Android文档:Android Keystore System,key material 可以绑定到Android设备的安全硬件(例如,可信赖执行环境(TEE),安全元素(SE)),一些文章将这称之为硬件支持存储,这意味着并不是所有的Android设备都支持这一点,如果设备不支持安全硬件,则将其存储在内部存储器中,某些文章称为软件备份存储。对于在软件备份存储中提取密钥是否可行,没有具体的实践,以至于不清楚其是否安全。还是记住那句话,nothing is 100% safe。

非对称加密

更安全的非对称加密选项是远程存储私钥。首次输入密码时,将其发送到服务器进行存储,同时也使用公钥加密并存储在shared preferences中。每当需要检查密码时,公钥加密的密码将被发送到后端服务器,并由私钥解密。然后检查服务器数据库中的密码信息。然后将令牌传递给Android客户端以允许访问该应用程序。手机上没有密码可见。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值