混淆整个 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 进行检查,您应该在其中找到诸如 a
、b
之类的函数调用,而不是它们的实际名称。
以上代码引用自 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 配置,android
和 ios
文件夹所在的位置。
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 代码的主要内容,如果未能解决你的问题,请参考以下文章
使用 redux 在 react-native 应用程序中保存访问令牌的最佳实践是啥?
如何将 expo react-native 自定义字体应用于整个容器
如何防止 map() 在 react-native 中一次渲染整个数组