简体   繁体   English

像“SERVER_URL”这样的属性应该存在于基于gradle的Android项目中?

[英]Where should properties like “SERVER_URL” live in a gradle-based Android project?

Where should I define constants like SERVER_URL or some static passwords in a Gradle Android project? 我应该在Gradle Android项目中哪里定义SERVER_URL等常量或一些静态密码? Obviously, I will use it in code. 显然,我会在代码中使用它。

  1. In build.gradle file as a build config field build.gradle文件中作为构建配置字段
  2. In gradle.properties file (I don't know how get these properties by code) gradle.properties文件中(我不知道如何通过代码获取这些属性)
  3. In another props file located in res folder 在另一个位于res文件夹中的props文件中

How secure is it in each case? 在每种情况下它有多安全?

Thanks. 谢谢。

There are two approaches in your question. 您的问题有两种方法。

1> To store static URL in your application 1>在应用程序中存储静态URL

The fact someone can see the URL doesn't matter (they could get this by sniffing the network anyway). 有人可以看到URL并不重要(他们可以通过嗅探网络得到这个)。 You probably want to ensure the request has come from a trusted client. 您可能希望确保请求来自可信客户端。 You can also maintain some key in request also. 您还可以在请求中维护一些密钥。

2> To store password in your application 2>在应用程序中存储密码

I found a good solution to store it in SharedPreferences with encryption. 我找到了一个很好的解决方案,可以将它存储在SharedPreferences中并加密。 Copy/Paste below code to create encrypted SharedPreferences. 复制/粘贴下面的代码以创建加密的SharedPreferences。

Simply wrap your own SharedPreferences object in this one, and any data you read/write will be automatically encrypted and decrypted. 只需将您自己的SharedPreferences对象包装在此对象中,您读/写的任何数据都将自动加密和解密。 eg. 例如。

final SharedPreferences prefs = new ObscuredSharedPreferences( 
this, this.getSharedPreferences(YOUR_PREFS_FILE_NAME, Context.MODE_PRIVATE) );

// eg.    
prefs.edit().putString("test","test").commit();
prefs.getString("test", null);

Class code, 班级代码,

/**
 * Warning, this gives a false sense of security.  If an attacker has enough access to
 * acquire your password store, then he almost certainly has enough access to acquire your
 * source binary and figure out your encryption key.  However, it will prevent casual
 * investigators from acquiring passwords, and thereby may prevent undesired negative
 * publicity.
 */
public class ObscuredSharedPreferences implements SharedPreferences {
    protected static final String UTF8 = "utf-8";
    private static final char[] SEKRIT = ... ; // INSERT A RANDOM PASSWORD HERE.
                                               // Don't use anything you wouldn't want to
                                               // get out there if someone decompiled
                                               // your app.


    protected SharedPreferences delegate;
    protected Context context;

    public ObscuredSharedPreferences(Context context, SharedPreferences delegate) {
        this.delegate = delegate;
        this.context = context;
    }

    public class Editor implements SharedPreferences.Editor {
        protected SharedPreferences.Editor delegate;

        public Editor() {
            this.delegate = ObscuredSharedPreferences.this.delegate.edit();                    
        }

        @Override
        public Editor putBoolean(String key, boolean value) {
            delegate.putString(key, encrypt(Boolean.toString(value)));
            return this;
        }

        @Override
        public Editor putFloat(String key, float value) {
            delegate.putString(key, encrypt(Float.toString(value)));
            return this;
        }

        @Override
        public Editor putInt(String key, int value) {
            delegate.putString(key, encrypt(Integer.toString(value)));
            return this;
        }

        @Override
        public Editor putLong(String key, long value) {
            delegate.putString(key, encrypt(Long.toString(value)));
            return this;
        }

        @Override
        public Editor putString(String key, String value) {
            delegate.putString(key, encrypt(value));
            return this;
        }

        @Override
        public void apply() {
            delegate.apply();
        }

        @Override
        public Editor clear() {
            delegate.clear();
            return this;
        }

        @Override
        public boolean commit() {
            return delegate.commit();
        }

        @Override
        public Editor remove(String s) {
            delegate.remove(s);
            return this;
        }
    }

    public Editor edit() {
        return new Editor();
    }


    @Override
    public Map<String, ?> getAll() {
        throw new UnsupportedOperationException(); // left as an exercise to the reader
    }

    @Override
    public boolean getBoolean(String key, boolean defValue) {
        final String v = delegate.getString(key, null);
        return v!=null ? Boolean.parseBoolean(decrypt(v)) : defValue;
    }

    @Override
    public float getFloat(String key, float defValue) {
        final String v = delegate.getString(key, null);
        return v!=null ? Float.parseFloat(decrypt(v)) : defValue;
    }

    @Override
    public int getInt(String key, int defValue) {
        final String v = delegate.getString(key, null);
        return v!=null ? Integer.parseInt(decrypt(v)) : defValue;
    }

    @Override
    public long getLong(String key, long defValue) {
        final String v = delegate.getString(key, null);
        return v!=null ? Long.parseLong(decrypt(v)) : defValue;
    }

    @Override
    public String getString(String key, String defValue) {
        final String v = delegate.getString(key, null);
        return v != null ? decrypt(v) : defValue;
    }

    @Override
    public boolean contains(String s) {
        return delegate.contains(s);
    }

    @Override
    public void registerOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener onSharedPreferenceChangeListener) {
        delegate.registerOnSharedPreferenceChangeListener(onSharedPreferenceChangeListener);
    }

    @Override
    public void unregisterOnSharedPreferenceChangeListener(OnSharedPreferenceChangeListener onSharedPreferenceChangeListener) {
        delegate.unregisterOnSharedPreferenceChangeListener(onSharedPreferenceChangeListener);
    }




    protected String encrypt( String value ) {

        try {
            final byte[] bytes = value!=null ? value.getBytes(UTF8) : new byte[0];
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
            SecretKey key = keyFactory.generateSecret(new PBEKeySpec(SEKRIT));
            Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
            pbeCipher.init(Cipher.ENCRYPT_MODE, key, new PBEParameterSpec(Settings.Secure.getString(context.getContentResolver(),Settings.System.ANDROID_ID).getBytes(UTF8), 20));
            return new String(Base64.encode(pbeCipher.doFinal(bytes), Base64.NO_WRAP),UTF8);

        } catch( Exception e ) {
            throw new RuntimeException(e);
        }

    }

    protected String decrypt(String value){
        try {
            final byte[] bytes = value!=null ? Base64.decode(value,Base64.DEFAULT) : new byte[0];
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
            SecretKey key = keyFactory.generateSecret(new PBEKeySpec(SEKRIT));
            Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
            pbeCipher.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(Settings.Secure.getString(context.getContentResolver(),Settings.System.ANDROID_ID).getBytes(UTF8), 20));
            return new String(pbeCipher.doFinal(bytes),UTF8);

        } catch( Exception e) {
            throw new RuntimeException(e);
        }
    }

}

Edit 编辑

You can use NDK to store password constant. 您可以使用NDK来存储密码常量。 To store and retrieve your key, you need to write the following code in our application. 要存储和检索密钥,您需要在我们的应用程序中编写以下代码。

static {
    System.loadLibrary("library-name");
}

public native String getSecretKey();

And save in a file using NDK the following function 并使用NDK保存在文件中以下功能

Java_com_example_exampleApp_ExampleClass_getSecretKey( JNIEnv* env,
                                              jobject thiz )
{
    return (*env)->NewStringUTF(env, "giveMeSecretKey".");
}

Now you can easily retrieve our key and use it to encrypt our data. 现在,您可以轻松检索我们的密钥并使用它来加密我们的数据。

byte[] keyPassword = getSecretKey().getBytes();

One approach would be to define every sensitive value in gradle.properties, and ensure that this file is excluded from VCS. 一种方法是在gradle.properties中定义每个敏感值,并确保从VCS中排除此文件。 You can then get Gradle to add string resources into your build, which are accessible in the normal way. 然后,您可以让Gradle将字符串资源添加到您的构建中,这些资源可以通过正常方式访问。 This has the added advantage that you can use different values for different product flavors. 这具有额外的优势,您可以为不同的产品口味使用不同的值。

// gradle.properties

MY_SECRET_PASSWORD=password



// build.gradle

buildTypes {
    debug {
        resValue "string", "my_secret_password", MY_SECRET_PASSWORD
    }
}


// MainActivity.java
String password = getString(R.string.my_secret_password);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 ANDROID STUDIO:此项目不是基于 gradle 的项目 - ANDROID STUDIO: this project is not a gradle-based project Android Studio更新Bumblebee后,该项目不是基于Gradle的项目 - After Android Studio Update Bumblebee, The project is not a Gradle-based project 在基于Android Gradle的项目中设置集成测试 - Setting up integration tests in Android Gradle-based project 在Android Studio上调试基于gradle的Java项目? - Debugging a gradle-based Java project on Android Studio? 如果Android项目不是基于Maven或Gradle的,我如何知道IntelliJ使用的是哪个版本的Android工具 - How can I tell which version of Android tools is used by IntelliJ if an Android project is not Maven or Gradle-based 该项目不是基于Gradle的项目。 如何从根目录打开项目? - The project is not a Gradle-based project. How do I open the project from the root directory? 使用基于Gradle的配置时,在Android Studio(IntelliJ)上运行简单的JUnit测试 - Running simple JUnit tests on Android Studio (IntelliJ) when using a Gradle-based configuration 对Google Cloud Messaging使用多个server_url - Using multiple server_url for Google Cloud Messaging Android studio gradle.properties 文件在哪里? - Android studio where is gradle.properties file? android studio项目中的gradle.properties丢失 - gradle.properties in android studio project missing
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM