【问题标题】:How to secure webservice URL?如何保护 Web 服务 URL?
【发布时间】:2019-01-06 20:28:19
【问题描述】:

我有一个带有网络服务 URL 的 Android 应用程序。如果有人解密我的 apk 文件,webservice url 将变得可见。我正在使用 HTTP POST 调用 web 服务。

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

我的注册页面 url 被黑了,并向该 url 发送批量请求和发布数据。我正在使用API_KEY 并发送带有帖子数据的API_KEYAPI_KEY 存储在 gradle.properties 文件中。

我没用过

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

经过一番搜索,我知道没有 100% 安全的方法可以隐藏 url。

我的注册码是:

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();

我不知道将数据发布到 Url 是否是正确的方法。

如何保护我的源代码?

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

我是安卓的初学者。请帮忙!

【问题讨论】:

  • 您需要在后端添加逻辑以使用您的 URL 访问任何服务需要由后端生成的访问令牌,因此即使有人获取 URL,它也无法在没有访问令牌的情况下使用 URL 访问服务.
  • @HareshChhelana 但他们可以从 apk 文件中找到访问令牌。
  • 很明显,你没有把它放在APK文件里。您通过其他方式向用户提供个人令牌。
  • @HareshChhelana 感谢您的回答。
  • 不明白为什么人们反对我的问题。

标签: android web-services security post encryption


【解决方案1】:

我在我开发的所有 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;

【讨论】:

  • 感谢您的回答。我有个疑问,反编译apk文件后能不能得到gradle.properties文件?
  • @Anoop.T 不,你可以从 jd-gui 查看 apk
  • 我在我的应用程序中使用了这种方法。它又被黑了。他们正在使用我的注册网址并不断发布数据。 minifyEnabled 在我的 build.gradle 文件中为 false。
  • "minifyEnabled 在我的 build.gradle 文件中为 false。" - 将其设置为 true 只会让黑客慢下来......一点点。
【解决方案2】:

没有办法保护“秘密”信息,例如嵌入在 APK 中的 URL。一个有决心/有动力的黑客可以击败任何您想要设计的方案......如果他/她可以访问您的应用程序正在运行的平台。

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

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

最重要的是,如果您将“秘密”网址嵌入到应用程序中并且该秘密被泄露并且您必须关闭/重新定位您的服务器,那么您将给所有人带来问题(合法、付费等)您的应用程序的用户。他们不会是快乐的露营者。

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

【讨论】:

    【解决方案3】:

    “URL”代表通用资源定位器。 URL 的全部意义在于访问某种资源,而要做到这一点,您显然必须告诉网络您正在连接到您想要获取的内容。

    现在,如果您担心黑客可以访问您的源代码,那么他当然也可以连接 Wireshark 或 Fiddler 并简单地观察您的应用正在建立哪些连接,以及您传递和接收的信息是什么。

    抱歉,我根本看不出有什么好的办法。

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

    【讨论】:

      【解决方案4】:

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

      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;
        

        }

      并通过使用它来描述它

        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 证书“https”并进行网络服务 POST。

      希望你明白我的意思。

      【讨论】:

      • 当 apk 被解密时,这样做有什么好处,用户将获得密钥(根 api 或基本 url),并且 apk 中可用的解密方法可以使用与 baaaammmnnn 相同的方法跨度>
      • @AbdulWaheed 没有办法 100% 保护您的代码,您必须尽可能努力。
      • @AbdulWaheed 请注意,encryptIt 方法是一个手动过程,+ 如何反编译 APK 将无法知道密钥是否存在于代码中,因为 progurde 将解密类名,除非他打开每个类,读取其中的每个方法,发现代码会进行加密。
      猜你喜欢
      • 2011-02-05
      • 1970-01-01
      • 2017-01-19
      • 2011-06-16
      • 2015-06-16
      • 2010-09-12
      相关资源
      最近更新 更多