如何在Android中安全地存储访问令牌和秘密?

我将使用oAuth从谷歌获取邮件和联系人。 我不想每次都要求用户login以获取访问令牌和秘密。 根据我的理解,我需要将它们与我的应用程序一起存储在数据库或SharedPreferences 。 但是我有点担心安全方面的问题。 我读过,你可以encryption和解密令牌,但是攻击者很容易只是反编译你的apk和类并获得encryption密钥。
在Android中安全存储这些令牌的最佳方法是什么?

将它们存储为共享首选项。 这些默认情况下是私人的,其他应用程序无法访问它们。 在根植设备上,如果用户明确允许访问正在尝试阅读的应用程序,则该应用程序可能能够使用它们,但无法防止这种情况发生。 至于encryption,你必须要求用户每次都input解密密码(这样就不能达到caching凭证的目的),或者把密钥保存到一个文件中,你也会遇到同样的问题。

存储令牌代替实际的用户名密码有一些好处:

  • 第三方应用程序不需要知道密码,用户可以确保只将其发送到原始网站(Facebook,Twitter,Gmail等)
  • 即使有人盗取了令牌,也不会看到密码(用户也可能在其他网站上使用该密码)
  • 令牌通常具有一定的寿命,并在一定时间后过期
  • 如果您怀疑他们已经被盗用,令牌可以被撤销

您可以将它们存储在AccountManager中 。 根据这些家伙,这被认为是最好的做法。

在这里输入图像说明

官方定义如下:

该课程提供对用户在线帐户的集中registry的访问。 用户每个帐户input一次凭据(用户名和密码),通过“一键”批准,允许应用程序访问在线资源。

有关如何使用AccountManager的详细指南:

  • Udi Cohen教程
  • Pilanites博客
  • Google IO演示文稿

但是,AccountManager最终只会将您的令牌存储为纯文本。 所以,我build议在将它们存储在AccountManager中之前先encryption你的秘密。 您可以使用各种encryption库,如AESCrypt或AESCrypto

另一个select是使用隐藏库 。 对于Facebook来说足够安全,而且比AccountManager更容易使用。 这是一个使用隐藏保存秘密文件的代码片段。

 byte[] cipherText = crypto.encrypt(plainText); byte[] plainText = crypto.decrypt(cipherText); 

希望这是有帮助的。

那么你可以通过休耕两个选项来确保你获得令牌。

  1. 使用保存您的访问令牌到Android密钥库不会相反。
  2. 使用NDK函数进行一些计算,将代码和NDK与c ++代码一起保存,这些代码很难反转