我有一个通过OAuth安全性与WebAPI交互的Android应用程序。为了获取访问令牌,我需要在请求的标头中发送OAuth凭证(即客户端ID和客户端密钥)。我的问题是,我应该在哪里保留这两个值(客户端ID和客户端密码),以便应用程序在需要时使用它。目前,我刚刚在通话中对其进行了硬编码。将它们保存在strings.xml文件中是否安全?
答案 0 :(得分:2)
请使用SharedPreferences
存储安全数据,因为如果任何人对您的应用程序进行反向工程,他们将获得硬编码字符串。 SharedPreferences
是一个安全的地方,您可以存储数据。
答案 1 :(得分:1)
如果您担心安全性,那么您可以通过在Android密钥库中加密和保存加密密钥来将数据保存在SharedPreference中。
密钥库不直接用于存储密码等应用程序机密,但是,它提供了一个安全的容器,应用程序可以使用它来存储私钥,对于恶意(未授权)用户来说非常困难。要检索的应用。
这是创建密钥库的好教程。 http://www.androidauthority.com/use-android-keystore-store-passwords-sensitive-information-623779/
答案 2 :(得分:0)
隐藏在BuildConfigs中
首先,在根目录中使用不同密钥的值创建文件apikey.properties
:
CONSUMER_KEY = XXXXXXXXXXX
CONSUMER_SECRET = XXXXXXX
为避免这些密钥出现在您的存储库中,请确保通过添加到.gitignore
文件中来排除该文件被检入:
apikey.properties
接下来,添加此部分以从app/build.gradle
文件中的该文件中读取。您还将创建编译时选项,这些编译时选项将使用buildConfigField
定义从该文件生成:
def apikeyPropertiesFile = rootProject.file("apikey.properties")
def apikeyProperties = new Properties()
apikeyProperties.load(new FileInputStream(apikeyPropertiesFile))
android {
defaultConfig {
// should correspond to key/value pairs inside the file
buildConfigField("String", "CONSUMER_KEY", apikeyProperties['CONSUMER_KEY'])
buildConfigField("String", "CONSUMER_SECRET", apikeyProperties['CONSUMER_SECRET'])
}
}
您现在可以使用Gradle提供的BuildConfig
对象在源代码中的任何位置访问这两个字段:
// inside of any of your application's code
String consumerKey = BuildConfig.CONSUMER_KEY;
String consumerSecret = BuildConfig.CONSUMER_SECRET;
答案 3 :(得分:0)
似乎您应该使用其他OAuth Flow。如您所知,Native Apps无法保守秘密。您可以在此处阅读有关OAuth和本机应用程序的建议。 https://tools.ietf.org/html/rfc8252
您可能想看看PKCE的授权代码流。在这里,您接受一个事实,即本机应用程序不能保密。您可以在这里找到有关流程的相对简单的解释:https://auth0.com/docs/flows/concepts/auth-code-pkce
作为替代方案,您可以查看动态客户端注册(https://tools.ietf.org/html/rfc7591),但这对于您的应用程序可能会显得过高。使用动态客户端注册,您不必对客户端密码进行硬编码
答案 4 :(得分:-2)
不,将它保存在strings.xml中是不安全的。请改用SharedPreferences
。例如:
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
然后按照以下方式存储您的客户端ID和客户端密码:
sharedPreferences.edit()
.putString("client_id", "your_client_id")
.putString("client_secret", "your_client_secret")
.apply();
从SharedPreferences获取客户端ID和客户端密钥:
String clientId = preferences.getString("client_id", "No ID");
String clientSecret = preferences.getString("client_secret", "No Secret");