如何在Android APP中隐藏API URL和参数?

Posted

技术标签:

【中文标题】如何在Android APP中隐藏API URL和参数?【英文标题】:How to hide API URL and parameters in Android APP? 【发布时间】:2018-03-30 17:16:55 【问题描述】:

我很想知道,如果没有商业产品进行混淆,有什么方法可以安全地存储无法在逆向工程中编译的 API url 和参数?我已经尝试了我所有的应用程序,它们的 API url 和代码很容易阅读。我担心安全问题。

【问题讨论】:

嘿@Chirag 找到任何解决方案?? @Abhishekkumar 没有,我没有找到任何合适的解决方案,从 API 方面做了更多的安全措施,并在 buildconfig 文件中定义了 url 仅作为示例.. API 有什么安全性? 您找到解决方案了吗?我也在寻找同样的东西。我通过 API 调用将机密令牌传递给远程服务器,即使经过混淆处理,我发现它暴露在我的 .class 文件中。 【参考方案1】:

在环境变量、BuildConfig 和 android Studio 中隐藏 Url

避免这种不良做法的一个简单方法是存储您的值 在环境变量中,所以只有你的机器知道,然后 以某种方式读取这些值并在构建时将它们注入您的代码中 时间。让我们看看如何使用 Android Studio、Gradle 和 构建配置。

首先,我们需要创建这些环境变量。在 Linux 和 Mac 中, 创建或编辑文件~/.gradle/gradle.properties(注意 实际的 Gradle 用户主目录位置)并添加一些值:

WEBServiceBaseURL="http://192.168.2.102:2323/"
WEBServiceBaseSMSURL="https://www.example.com/"

其次,在模块的 build.gradle 文件中,添加这些行

//Add these lines
def Base_URL = '"' + WEBServiceBaseURL + '"' ?: '"Define BASE URL"';
def SMS_Base_URL = '"' + WEBServiceBaseSMSURL + '"' ?: '"Define SMS BASE URL"';

android.buildTypes.each  type ->
    type.buildConfigField 'String', 'Base_URL', WEBServiceBaseURL
    type.buildConfigField 'String', 'SMS_Base_URL', WEBServiceBaseSMSURL

在Java文件中使用

BuildConfig.Base_URL 它将返回 URL 字符串

  public static Retrofit getClient() 
        if (retrofit==null) 
            retrofit =new Retrofit.Builder()
                    .baseUrl(BuildConfig.Base_URL)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        
        return retrofit;
    

【讨论】:

无法根据您的想法隐藏 URL。 反编译时很容易找到 @erfan 是否有任何其他方式? @Sagar Zala 请以其他方式分享您的知识 @erfan 可以分享一下我们反编译apk文件时如何获取gradle.properties文件吗?【参考方案2】:

我找到了一个解决方案来隐藏基本 url 以确保 NDK 保护 api。将 base64 编码的字符串保存在 cpp 文件中,并从 java 类中调用它并解码 base64。

在您的项目中包含 c++ (NDK) 支持。您可以将其包含到您的新项目或旧项目中。

你的 cpp 文件名可以是 (native-lib.cpp)

搜索在线 base64 编码器并编码您的基本网址。现在将编码字符串保存在 cpp 文件中

里面的cpp文件示例代码是这样的:

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring JNICALL
Java_com_touhidapps_MyProject_utils_MyConstants_baseUrlFromJNI(JNIEnv *env, jobject) 
    std::string mUrl = "aHR0cDovL2FwaS5leGFtcGxlLmNvbS8="; //"http://api.example.com/";
    return env->NewStringUTF(mUrl.c_str());

在 MyConstants.java 类中:(我保存了所有 api url。)

// load c++ library
static 
    System.loadLibrary("native-lib");


public static native String baseUrlFromJNI();

// decode base64 to a string and get normal url
public static String getSecureBaseUrl() 
    String mUrl = baseUrlFromJNI();
    try 
        String text = new String(Base64.decode(mUrl, Base64.DEFAULT), "UTF-8");
        return text;
     catch (UnsupportedEncodingException e) 
        e.printStackTrace();
    
    
    mUrl = "http://demo.example.com/"; // don't change this link. This will not execute normally, if exception happens then it will return a demo url.
    return mUrl;

现在您可以获得如下所示的原始网址:

public static final String API_BASE = "" + getSecureBaseUrl();

【讨论】:

这是万无一失的解决方案吗? @ShivamSharma 我不这么认为。 mUrl = "demo.example.com"; Java文件中的这一行,因此可以提取相同的内容。' @AliAhmed 不要更改此链接。这将无法正常执行,如果发生异常,它将返回一个演示 url 并防止您的应用程序崩溃。 cpp文件中的url更改。【参考方案3】:

您的问题不适合 ***,因为该主题过于宽泛且主要基于意见。但是,我想我可以在这里分享一些我的想法作为答案。

使用代码混淆来隐藏 API url 绝对是一个好主意,如果你想隐藏它们,它在某些情况下也可以工作。您也可以考虑在代码中加密 API url,并将加密的 url 存储在您的 SharedPreferences 或本地存储中,每次使用 API url 调用 Web 服务时都需要再次解密。

但这些都不能确保您的 API 网址是不可破解的。如果有人真的想获得您的 API 网址,他/她可以通过跟踪您用来调用 Web 服务的网络轻松获得这些网址。

因此,在大多数情况下,加密 API url 和混淆变量名以隐藏 API url 不会像您预期的那样起作用。是的,在获取您的 API 网址时,我也没有发现任何安全漏洞。因为,API 服务器的设计应该能够阻止攻击者通过 API 进行的不需要的服务调用。您可能会考虑考虑在您的主机中设置防火墙,或者可以设置一个基本的身份验证协议来保护您的数据。有很多方法可以防止这些安全漏洞活动。您也可以考虑阅读this article,我发现它有助于了解如何保护您的 API 不被滥用。

希望对您有所帮助。

【讨论】:

以上是关于如何在Android APP中隐藏API URL和参数?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Android 应用程序中隐藏 API 密钥? [复制]

如何隐藏android app图标

在 react/redux 应用程序(代理)中隐藏 api url

如何在 PWA Android 应用中隐藏 URL 栏?

如何在 Youtube Player android API 中隐藏控件、全屏按钮?

如何调用Android隐藏API