混淆整个 React Native 应用程序,包括 JavaScript 代码

Posted

技术标签:

【中文标题】混淆整个 React Native 应用程序,包括 JavaScript 代码【英文标题】:Obfuscate entire React Native app including JavaScript code 【发布时间】:2019-03-12 19:31:38 【问题描述】:

如何混淆我的 react-native JS 代码?我在 build.gradle 文件中设置了以下内容:

release 
      minifyEnabled true
      proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
 

这是我的 proguard-rules.pro 文件(默认):

# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the javascript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview 
#   public *;
#

但是在解压apk之后我仍然可以找到我的JS组件名称、变量和url的

【问题讨论】:

【参考方案1】:

由于您的 React Native JavaScript 代码是基于 Android 和 ios 的本机代码构建的,因此整个混淆过程将考虑所有三个代码库:

混淆 Android 的 Java 代码

幸运的是,您的项目已经包含Proguard 混淆器,可以按如下方式启用:

    在位于android/app/ 文件夹中的build.gradle 文件中更新您的发布配置:

    def enableProguardInReleaseBuilds = true
    
    android 
        // other config omitted for brevity
        buildTypes 
            release 
                debuggable false
                shrinkResources enableProguardInReleaseBuilds
                zipAlignEnabled enableProguardInReleaseBuilds
                minifyEnabled enableProguardInReleaseBuilds
                useProguard enableProguardInReleaseBuilds
                setProguardFiles([getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'])
            
        
    
    

    在位于android/app/ 文件夹中的proguard-rules.pro 文件中启用 ProGuard 混淆并相应地编辑规则。

    下面这行代码需要注释掉(在行首添加#):

    #-dontobfuscate
    

    在此阶段,构建您的 Android 应用的发布版本应包含经过混淆的 Java 代码。通过分析您的 APK 进行检查,您应该在其中找到诸如 ab 之类的函数调用,而不是它们的实际名称。

以上代码引用自 Maria Korlotian's Medium post。还要检查来自 GitHub 存储库的 latest default React Native ProGuard configuration。

从 Android 3.3 beta 开始,可以使用更优化的混淆器R8。

混淆 iOS 的 Objective-C 代码

iOS 项目中没有内置库会混淆您的代码,因此必须使用外部包。 PPiOS-Rename 和 ObjC-Obfuscator 是这里的两个选项。详细文档可以在他们的 GitHub 存储库中找到。

混淆 JavaScript 代码

这将是混淆中最重要的部分,因为我们的实际代码是用 JavaScript 编写的。 react-native-obfuscating-transformer npm 包可以在这里使用:

    将包添加到您的项目中

    npm install react-native-obfuscating-transformer
    

    在项目根目录的 rn-cli.config.js 中添加/更新 CLI 配置,androidios 文件夹所在的位置。

    module.exports = 
     getTransformModulePath() 
       return require.resolve("./transformer")
     ,
    
    

    如果此文件尚不存在,则创建此文件。

    也在根目录下创建transformer.js 文件并酌情指定configuration options:

    const obfuscatingTransformer = require("react-native-obfuscating-transformer");
    
    module.exports = obfuscatingTransformer(
        /* Insert here any required configuration */
    );
    

    特别注意混淆过程的范围,默认情况下只针对src/文件夹中的文件(默认不包括node_modules)。


如上所述,混淆您的应用程序并不会使其具有内在的安全性 - 尽管安全性隐蔽性可能比仅前者更好,但还有许多其他安全增强功能(如果不是要求)可以在 React Native 应用程序中实现。这包括将敏感信息存储在安全存储中(Android 中的Keystore / iOS 中的Keychain)、在适当的情况下实施certificate pinning 等。

其他有用的链接:

Secure Storage in React Native 兰迪·库尔曼

Strengthen TLS in React Native through Certificate Pinning 来自 Skip Hovsmith

【讨论】:

除了 react-native-obfuscating-transformer 还有其他的 javascript 混淆工具吗 @SamyakUpadhyay 你有没有试过在 GitHub 中打开这方面的问题?这是我所知道的唯一一个专门针对 React Native 的,它基于 javascript-obfuscator @Siavas 我怎么知道我的 apk 被混淆了? @Siavas 你能告诉我如何检查我的混淆代码的结果吗? @RobinHuy 实际上本机应用程序仍然包含 JavaScript 代码。当您遇到错误时,您将能够观察到这一点,例如,如果应用程序是为开发而构建的。这种通常称为“桥接”的架构对于 React Native 来说是相当独特的。 This answer 非常简洁地涵盖了这一点,而 linked post 将为您提供对该概念的广泛描述。【参考方案2】:

@Siavas 的上述回答涵盖了大部分内容,但是 Metro 插件 react-native-obfuscating-transformer 似乎并没有混淆 index.android.bundle,您可以尝试 obfuscator-io-metro-plugin 这似乎是工作正常。它也是基于javascript-obfuscator

您需要在metro.config.js 中包含以下配置

const jsoMetroPlugin = require("obfuscator-io-metro-plugin")(
  
    // these option are obfuscation options from javascript-obfuscator
    compact: false,
    sourceMap: true,
    controlFlowFlattening: true,
    controlFlowFlatteningThreshold: 1,
    numbersToExpressions: true,
    simplify: true,
    shuffleStringArray: true,
    splitStrings: true,
    stringArrayThreshold: 1,
  ,
  
    runInDev: false /* optional */,
    logObfuscatedFiles: true /* optional generated files will be located at ./.jso */,
  
);
 
module.exports = 
  transformer: 
    getTransformOptions: async () => (
      transform: 
        experimentalImportSupport: false,
        inlineRequires: false,
      ,
    ),
  ,
  ...jsoMetroPlugin,
;

【讨论】:

这个库是否也混淆了 iOS 项目,还是仅混淆了 Android?

以上是关于混淆整个 React Native 应用程序,包括 JavaScript 代码的主要内容,如果未能解决你的问题,请参考以下文章

React Native 数组道具混淆

使用 redux 在 react-native 应用程序中保存访问令牌的最佳实践是啥?

如何将 expo react-native 自定义字体应用于整个容器

如何防止 map() 在 react-native 中一次渲染整个数组

是否可以在 React Native 中设置整个应用程序的背景? [复制]

react-native 应用程序中如何保护敏感数据