如何保护Web服务URL?

时间:2017-11-08 07:45:40

标签: android web-services security post encryption

我有一个带有网络服务网址的Android应用。如果有人解密我的apk文件,webservice url将变为可见。我正在使用HTTP POST来调用Web服务。

任何人都可以通过从this site反编译apk文件来阅读代码。

我的注册页面网址被黑客入侵,并通过发布数据向此网址发送批量请求。我使用API_KEY并发送API_KEY发布数据。 API_KEY存储在gradle.properties文件中。

我没用过

 minifyEnabled true
 shrinkResources true
 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'`  when its got hacked.

经过一些搜索,我知道没有100%安全方法可以隐藏网址。

我的注册代码是:

String link = "http://xxxxxxxxxx.php";

String data = URLEncoder.encode("name", "UTF-8") + "=" + URLEncoder.encode(name, "UTF-8");
data += "&" + URLEncoder.encode("phone", "UTF-8") + "=" + URLEncoder.encode(phone, "UTF-8");
data += "&" + URLEncoder.encode("password", "UTF-8") + "=" + URLEncoder.encode(password, "UTF-8"); 

URL url = new URL(link);
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
wr.flush();

我不知道将数据发布到网址是否正确。

如何保护我的源代码?

我可以将所有网络服务网址存储在服务器中吗?

我是android的初学者。请帮忙!

4 个答案:

答案 0 :(得分:5)

我在我开发的所有Android应用程序中使用它

  

gradle.properties

API = http://ec2xxxxx.compute.amazonaws.com
API_KEY = $2c11SoL/NjJ28

创建utils.gradle

  

utils.gradle

        class Utils {
        static def r = new Random(System.currentTimeMillis())
    }

    def String toJavaCodeString(String string) {
        byte[] b = string.getBytes();
        int c = b.length;
        StringBuilder sb = new StringBuilder();

        sb.append("(new Object() {");
        sb.append("int t;");
        sb.append("public String toString() {");
        sb.append("byte[] buf = new byte[");
        sb.append(c);
        sb.append("];");

        for (int i = 0; i < c; ++i) {
            int t = Utils.r.nextInt();
            int f = Utils.r.nextInt(24) + 1;

            t = (t & ~(0xff << f)) | (b[i] << f);

            sb.append("t = ");
            sb.append(t);
            sb.append(";");
            sb.append("buf[");
            sb.append(i);
            sb.append("] = (byte) (t >>> ");
            sb.append(f);
            sb.append(");");
        }

        sb.append("return new String(buf);");
        sb.append("}}.toString())");

        return sb.toString();} 
ext.toJavaCodeString = this.&toJavaCodeString
  

的build.gradle

apply from: "utils.gradle"
   android {
    defaultConfig {
        buildConfigField 'String', 'API', toJavaCodeString(API)
        buildConfigField 'String', 'API_KEY', toJavaCodeString(API_KEY)
    }}

并访问您的私人网址;

    public static final String API = BuildConfig.API;

答案 1 :(得分:2)

无法保护“秘密”信息,例如嵌入在APK中的网址。一个坚定/有动力的黑客可以击败你想要设计的任何计划......如果他/她可以访问你的应用程序正在运行的平台。

为了让您的应用运行,用户设备上运行的应用需要能够解密隐藏的网址。用户可以在应用程序的地址空间中以解密的形式拦截URL,或者他/她可以对您用于解密的算法和解密密钥进行反向工程。

另一个“攻击”是你的应用需要使用URL来发出请求。该请求可以在用户设备上截获,然后由SSL / TLS通道保护到您的(可能是)支持HTTPS的服务。

最重要的是,如果你将一个“秘密”URL嵌入到一个应用程序中并且该秘密遭到破坏而你必须关闭/重新安置你的服务器,那么你就会为所有人制造问题(合法,付费等)您应用的用户。他们不会是快乐的露营者。

正确的方法是使您的服务安全......并使用某种身份验证机制,以便黑客不仅需要URL来发出请求。可以/应该向用户颁发个人凭证(例如,授权密钥),并且您需要实现一种在服务器端使给定用户的凭证无效的方法。

答案 2 :(得分:0)

“URL”代表Universal Resource Locator。 URL的重点是访问某种资源,为此,您显然必须告诉网络您要连接到要获取的内容。

现在,如果您担心黑客可以访问您的源代码,那么他肯定也可以连接Wireshark或Fiddler,只需观察您的应用程序正在建立什么连接,以及您传递和接收的信息。

很抱歉,但我根本看不出任何好办法。

如果您担心自己的服务器/服务遭到黑客入侵或DOS操作,我认为您最好尽可能专注于保护它们,而不是试图隐藏它们。

答案 3 :(得分:-1)

我已经用两种方式解决了这个问题

  1. 使用我的私钥加密我的代码中的URL,并在请求呼叫时再次解密,

    public static String encryptIt(String value) {
    try {
        DESKeySpec keySpec = new DESKeySpec(new byte[]{105, 107, 18, 51, 114, 83, 51, 120, 121}); 
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey key = keyFactory.generateSecret(keySpec);
    
        byte[] clearText = value.getBytes("UTF8");
        // Cipher is not thread safe
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(Cipher.ENCRYPT_MODE, key);
    
        //   Log.d("aa", "Encrypted: " + value + " -> " + encrypedValue);
        return Base64.encodeToString(cipher.doFinal(clearText), Base64.DEFAULT);
    } catch (Exception e) {
        e.printStackTrace();
    }
    return value;
    

    }

  2. 并使用此

    进行描述
      public static String decryptIt(String value) {
        try {
            DESKeySpec keySpec = new DESKeySpec(new byte[]{105, 107, 18, 51, 114, 83, 51, 120, 121});//cryptoPass.getBytes("UTF8"));
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey key = keyFactory.generateSecret(keySpec);
    
            byte[] encrypedPwdBytes = Base64.decode(value, Base64.DEFAULT);
            // cipher is not thread safe
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] decrypedValueBytes = (cipher.doFinal(encrypedPwdBytes));
    
            // Log.d("aa", "Decrypted: " + value + " -> " + decrypedValue);
            return new String(decrypedValueBytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return value;
    }
    

    请注意,在我的情况下,私钥是new byte[]{105, 107, 18, 51, 114, 83, 51, 120, 121}我认为它是$ecrEt或类似我遗忘的东西。

    因此,如果他们反编译APK,他们就无法在您的代码中找到服务链接。

    所以基本网址就像这个public static final String ROOT_API = "aHR0cHSC86LSy9tbS2JpuZW50aWtoYWAbGUJhdC5qbw==";

    2-此外,您必须在代码中添加progaurd

    但是,如果黑客是预付人,他们可以浏览网络并查找网址,在这种情况下,您必须使用SSl证书&#34; https&#34;并进行webserivce POST。

    希望你明白我的意思。