如何在 Android 应用程序中安全地存储凭据(密码)?

Posted

技术标签:

【中文标题】如何在 Android 应用程序中安全地存储凭据(密码)?【英文标题】:How to securely store credentials (password) in Android application? 【发布时间】:2012-06-14 23:46:35 【问题描述】:

我想将用于登录我正在开发的金融应用程序的密码存储在安全的地方。在做了一些网上冲浪后,我发现了以下选项,但每个选项都有一定的缺点。

1) 钥匙串。 仅适用于操作系统版本 4。

2) 共享偏好。 它以纯文本形式存储数据,即使我对数据进行了加密,也可以通过反编译应用程序代码来破坏加密密钥。

3) 访问密钥库守护进程并将凭据存储在其中。 (http://nelenkov.blogspot.com/2012/05/storing-application-secrets-in-androids.html) 需要另一个密码才能记住。

请建议我一种更好的方法来保护 Android 应用程序(如 iPhone KeyChain)中的凭据信息。

【问题讨论】:

见***.com/questions/1925486/… 【参考方案1】:

散列是解决方案 不要将凭据作为纯文本存储在共享首选项或任何媒体中。

只需对密码进行加盐和哈希处理,然后您就可以继续将其存储在 sharedPreferences 或某些嵌入式数据库中。

工作原理如下:

在线

    普通(未散列)密码被发送到服务器进行身份验证和 登录成功后授权。

    盐可以生成并从服务器返回到客户端 或者可以在客户端生成

    然后将其存储为盐并哈希密码并存储它。

离线

    我们将使用我们存储的盐对用户输入的密码进行哈希处理

    我们将与成功登录时存储的哈希值进行比较

    如果两者相等,那么我们会让用户进入,否则我们不会让用户进入。

优点:

    所以现在您不必担心版本兼容性问题了。

    即使设备已植根,也很难暴力破解哈希。

    即使有人反编译/破解了应用程序,也很难进行逆向工程

【讨论】:

通过散列存储的问题是散列旨在成为单向街道。我相信用户希望存储密码,以便他们可以回忆它,以使用户不必每次都登录。加密是一条双向的道路,设计的哈希不是。 我认为开发人员希望允许用户离线登录。所以正如您所说,哈希是一种无法逆向工程的方式,因此如果哈希匹配则其高度安全,则身份验证成功。 是的,这对于离线身份验证来说是理想的。我将财务应用程序解释为您需要凭据才能通过 Web 服务的身份验证以获取信息。在您的回答中注意离线方面可能会有所帮助。 @RQube - salt 必须是动态的,salt 生成逻辑可以是服务器生成的,这样反编译应用程序就不会向黑客泄露 salt 生成逻辑。 我不明白这样做的好处。如果服务器从期望密码(然后散列)更改为期望预散列密码,那么如果散列密码被泄露,黑客可以使用它登录服务器。他们永远不必担心真正的密码是什么他们拥有服务器认为的“密码”【参考方案2】:

目前在 Android 中不等同于 iPhone 的 KeyChain。如果您想保密,请不要将其存储在设备上。或者至少,不要将加密的密钥/密码存储在设备上。就那么简单。

另外:

1) 即使在 ICS 上,您也不能直接使用 KeyChain 来存储应用程序机密(请参阅 3 中的博文)

2) 这仅适用于 root 手机,或者如果有人可以物理访问该设备。

3) 记住一个密码,保护所有的凭据,比记住多个密码要好得多。此外,在 ICS 上,没有单独的密码,凭证存储受设备解锁密码保护。

【讨论】:

我决定继续使用第三个选项。我现在面临的一个问题是密钥库将每个条目与应用程序 UID 相关联。因此,如果安装另一个与前一个应用程序具有相同包名的应用程序(当然我必须先删除前一个应用程序)和不同的应用程序签名(签名证书),那么该应用程序也可以查看密钥库条目,因为 UID 不会改变。 你确定吗?如果您安装不同的应用程序,UID 会发生变化。 实际上我正在尝试破解我自己的应用程序。为此,我开发了另一个具有相同包名的应用程序并尝试将其安装在我的设备上(这里这个新应用程序的签名证书与实际应用程序不同)。安装此应用程序后,android 给我一个错误“已安装具有冲突签名的同名现有包”。因此,我删除了以前的应用程序并安装了新的应用程序。在这一点上,而不是分配新的应用程序 android 分配与分配给以前的应用程序相同的 UID。 发生这种情况的设备和 Android 版本是什么?您确实能够从“新”应用程序中访问密钥吗? 我知道这是旧的,但在最新的 Android 主分支中,应用程序卸载时应用程序的密钥被删除,因此这应该不是问题。话虽如此,界面也发生了很大变化,因此博客中的代码很可能不会像在下一个 Android 版本(K-whatever)中那样工作。

以上是关于如何在 Android 应用程序中安全地存储凭据(密码)?的主要内容,如果未能解决你的问题,请参考以下文章

IBM 工作灯。是不是可以安全地存储用户凭据并在没有用户交互的情况下恢复它们?

在 GitLab 中安全地存储秘密和凭据

MySQL / 存储 MySQL 凭据

如何在移动应用程序中安全地存储密码

如何在爬网程序中安全地使用用户输入的凭据?

Git http - 安全地记住凭据