【问题标题】:User data in account manager is accessible by other applications其他应用程序可以访问帐户管理器中的用户数据
【发布时间】:2015-05-22 05:44:00
【问题描述】:

我正在尝试利用 Android 的客户管理器来存储用户的应用凭据。 虽然我没有保存用户的密码,但我想将其他安全密钥保存到帐户的 UserData。根据下面引用的文档,具有不同 UID 的应用程序不应访问它。

public String getUserData(账户账号,String key)

获取与帐户关联的以“key”命名的用户数据。这适用于身份验证器和相关代码,以存储任意元数据以及帐户。键和值的含义取决于帐户的身份验证器。

从主线程调用这个方法是安全的。

此方法要求调用者持有AUTHENTICATE_ACCOUNTS权限,并与账户的验证者具有相同的UID。

参数 account - 查询用户数据的账户 退货 用户数据,如果帐号或密钥不存在则为空

为了测试这一点,我创建了一个应用程序,它创建一个帐户并将一些内容保存到 UserData。我还创建了另一个访问第一个应用程序帐户的应用程序。以下是sn-ps:

第一个应用:

AccountManager am = (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);
final Account account = new Account("Account Name", "my.account.type");
am.addAccountExplicitly(account, null, null);
am.setAuthToken(account, "my.account.type", "some auth token");
am.setUserData(account, "key.for.secure.user.data", "some secure data");

第二个应用:

AccountManager am =  (AccountManager)context.getSystemService(Context.ACCOUNT_SERVICE);
Account[] accountsFromFirstApp = am.getAccountsByType("my.account.type");
for(Account acct: accountsFromFirstApp){
    printToLogs(acct.name);
    printToLogs(am.getUserData(acct, "key.for.secure.user.data"));
}

根据上面的文档,我预计第二个应用程序的 getUserData() 会返回一个异常,因为它的 UID 与所有者应用程序不同。令人惊讶的是,我能够毫无错误地访问第一个应用程序的用户数据。

但是当我尝试使用“com.google”作为 accountType 从 google 访问帐户时,我得到了预期的异常。

我的实现有什么问题?我是否错过了 Android 文档中未说明的一些配置?任何帮助将不胜感激。

再想一想,如果可以轻松访问这些用户数据(假设其他应用程序知道我的应用程序的帐户类型),那么将字符串存储在 UserData 中与将它们存储在 SharedPreferences 中有何区别?

【问题讨论】:

  • 您使用的是哪个安卓版本?您是否使用不同的签名证书在发布模式下编译了这两个应用程序?您的应用清单是否包含manifest android:sharedUserId?两个应用是否有不同的manifest packagename
  • 在测试时,我使用了几个 android 版本,例如 KitKat 和 JellyBean 的变体。我还没有尝试在发布模式下编译它们。我没有指定 android:sharedUserId 并且我确定它们具有不同的 UID,因为我也将它们放入日志中。它们也有不同的包名。
  • 现在我正在重新阅读回复,如果我使用不同的签名证书来回答 k3b 的问题,我没有。它实际上是我用来测试它的同一个调试证书。但是文档没有说明这一点。这真的很重要吗?

标签: android security sharedpreferences account accountmanager


【解决方案1】:

如果您的数据是个人数据,您可以对其进行加密,因此其他应用无法读取它们。

I.E 像这样使用 AES 加密:

public class AESCryptor
{
    private static final String ALGORITHM = "AES";
    // 16-bit Key for encryption (Change to yours)
    private static final String KEY = "XXXXXXXXXXXXXXX";

    public static String encrypt(String value) throws Exception
    {
        Key key = generateKey();
        @SuppressLint("GetInstance") Cipher cipher = Cipher.getInstance(AESCryptor.ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte [] encryptedByteValue = cipher.doFinal(value.getBytes("utf-8"));
        return Base64.encodeToString(encryptedByteValue, Base64.DEFAULT);

    }

    public static String decrypt(String value) throws Exception
    {
        Key key = generateKey();
        @SuppressLint("GetInstance") Cipher cipher = Cipher.getInstance(AESCryptor.ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] decryptedValue64 = Base64.decode(value, Base64.DEFAULT);
        byte [] decryptedByteValue = cipher.doFinal(decryptedValue64);
        return new String(decryptedByteValue,"utf-8");

    }

    private static Key generateKey() {
        return new SecretKeySpec(AESCryptor.KEY.getBytes(),AESCryptor.ALGORITHM);
    }
}

我在我的应用程序中使用它,并且它有效!

这可能无法回答问题

其他应用程序可以访问帐户管理器中的用户数据

但它由@thomas-s-e 回答

问候, @developerfromjokela

【讨论】:

  • 什么是有人通过反编译应用获得了你的密钥?
  • 使用密钥库存储随机加密密钥,但这值得拥有自己的线程。
【解决方案2】:

来自 AccountManager 文档:

此类提供对用户在线帐户的集中注册表的访问。用户为每个帐户输入一次凭据(用户名和密码),通过“一键式”批准授予应用程序访问在线资源的权限。

由 AccountManager 管理的帐户是集中式和可重复使用的,例如所有 Google 应用都可以使用同一个帐户,而且并非每个应用都必须创建自己的 Google 帐户。

据我所知,AccountManager 的想法之一是拥有可重复使用的帐户,可从不同的应用程序访问。

但由于存储的凭据可以从不同的位置访问,因此您不应在 AccountManager 中存储任何纯文本密码。

愿这个话题对你感兴趣:What should I use AccountManager for?

【讨论】:

  • 感谢您的回复!我想这个答案是针对我最后一个关于使用 AccountManager 优于 SharedPreferences 的问题。尽管我理解您所说的想法,但我主要担心的是客户经理方法没有返回与 AccountManager.documentation 中所述相反的异常。有什么想法吗?
  • 可能是因为您使用调试密钥库对它们都进行了签名?我目前没有其他想法......
  • 我测试了相同和不同的密钥库应用程序。所以我确认托马斯的回答是正确的。使用不同的密钥库,您不会遇到异常,但 AccountManger 中的 getAccountsByType() 返回一个空数组。
猜你喜欢
  • 2012-12-18
  • 1970-01-01
  • 2015-08-13
  • 2011-10-22
  • 2015-08-27
  • 1970-01-01
  • 1970-01-01
  • 2013-03-23
  • 1970-01-01
相关资源
最近更新 更多