StringFog

Introduction: 一款自动对字节码中的字符串进行加密 Android 插件工具
More: Author   ReportBugs   
Tags:

一款自动对 dex/aar/jar 文件中的字符串进行加密 Android 插件工具,正如名字所言,给字符串加上一层雾霭,使人难以窥视其真面目。

  • 支持 java/kotlin。
  • 支持 app 打包生成的 apk 加密。
  • 支持 aar 和 jar 等库文件加密。
  • 支持加解密算法的自主扩展。
  • 支持配置可选代码加密。
  • 完全 Gradle 自动化集成。
  • 不支持 InstantRun。

一些提示

由于我目前主要精力在Reqable创业项目上,StringFog 的 Issue 处理没那么及时,非常抱歉! 虽然我已经很久不从事 Android 项目的开发,但是还是会尽力将 StringFog 一直维护下去,如果您发现了一些可以修复的问题,欢迎提交 PR。

原理


  • 加密前:

    String a = "This is a string!";
    
  • 加密后: ```java String a = StringFog.decrypt(new byte[]{-113, 71...}, new byte[]{-23, 53});


- 运行时:
```java
decrypt: new byte[]{-113, 71...} => "This is a string!"

混淆

StringFog 和混淆完全不冲突,也不需要配置反混淆,实际上 StringFog 配上混淆效果会更好!

使用

由于开发了 gradle 插件,所以在集成时非常简单,不会影响到打包的配置。插件已经上传到 MavenCentral,直接引用依赖就可以。 jcenter 已经废弃,3.0+版本取消发布

1、在根目录 build.gradle 中引入插件依赖。
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        ...
        classpath 'com.github.megatronking.stringfog:gradle-plugin:5.1.0'
        // 选用加解密算法库,默认实现了 xor 算法,也可以使用自己的加解密库。
        classpath 'com.github.megatronking.stringfog:xor:5.0.0'
    }
}
2、在 app 或 lib 的 build.gradle 中配置插件。
apply plugin: 'stringfog'

// 导入 RandomKeyGenerator 类,如果使用 HardCodeKeyGenerator,更换下类名
import com.github.megatronking.stringfog.plugin.kg.RandomKeyGenerator
import com.github.megatronking.stringfog.plugin.StringFogMode

stringfog {
    // 必要:加解密库的实现类路径,需和上面配置的加解密算法库一致。
    implementation 'com.github.megatronking.stringfog.xor.StringFogImpl'
    // 可选:StringFog 会自动尝试获取 packageName,如果遇到获取失败的情况,可以显式地指定。
    packageName 'com.github.megatronking.stringfog.app'
    // 可选:加密开关,默认开启。
    enable true
    // 可选:指定需加密的代码包路径,可配置多个,未指定将默认全部加密。
    fogPackages = ['com.xxx.xxx']
    // 可选(3.0 版本新增):指定密钥生成器,默认使用长度 8 的随机密钥(每个字符串均有不同随机密钥),
    // 也可以指定一个固定的密钥:HardCodeKeyGenerator("This is a key")
    kg new RandomKeyGenerator()
    // 可选(4.0 版本新增):用于控制字符串加密后在字节码中的存在形式, 默认为 base64,
    // 也可以使用 text 或者 bytes
    mode StringFogMode.base64
}

kts 中配置参考

plugins {
    //...lib or application
    id("stringfog")
}
apply(plugin = "stringfog")

configure<StringFogExtension> {
    // 必要:加解密库的实现类路径,需和上面配置的加解密算法库一致。
    implementation = "com.github.megatronking.stringfog.xor.StringFogImpl"
    // 可选:加密开关,默认开启。
    enable = true
    // 可选:指定需加密的代码包路径,可配置多个,未指定将默认全部加密。
    // fogPackages = arrayOf("com.xxx.xxx")
    kg = com.github.megatronking.stringfog.plugin.kg.RandomKeyGenerator()
    // base64 或者 bytes
    mode = com.github.megatronking.stringfog.plugin.StringFogMode.bytes
}
3、在 app 或 lib 的 build.gradle 中引入加解密库依赖。
dependencies {
      ...
      // 这里要和上面选用的加解密算法库一致,用于运行时解密。
      compile 'com.github.megatronking.stringfog:xor:5.0.0'
}
注意事项

从 AGP 8.0 开始,默认不生成 BuildConfig,但是 StringFog 依赖此配置,请注意加上下面的配置。

android {
    // 注意请加上此配置
    buildFeatures {
        buildConfig = true
    }
    ...
}

扩展

注解反加密

如果开发者有不需要自动加密的类,可以使用注解 StringFogIgnore 来忽略:

@StringFogIgnore
public class Test {
    ...
}

自定义加解密算法实现

实现 IStringFog 接口,参考 stringfog-ext 目录下面的 xor 算法实现。 注意某些算法在不同平台上会有差异,可能出现在运行时无法正确解密的问题。如何集成请参考下方范例!

public final class StringFogImpl implements IStringFog {

    @Override
    public byte[] encrypt(String data, byte[] key) {
        // 自定义加密
    }

    @Override
    public String decrypt(byte[] data, byte[] key) {
        // 自定义解密
    }

    @Override
    public boolean shouldFog(String data) {
        // 控制指定字符串是否加密
        // 建议过滤掉不重要或者过长的字符串
        return true;
    }

}

自定义密钥生成器

实现 IKeyGenerator 接口,参考 RandomKeyGenerator 的实现。

Mapping 文件

注意⚠️:StringFog 5.x 版本起有问题,已暂时停用此功能 加解密的字符串明文和暗文会自动生成 mapping 映射文件,位于 outputs/mapping/stringfog.txt。

范例

  • 默认加解密算法集成,参考sample1
  • 自定义加解密算法集成,参考sample2

更新日志

v5.1.0

  • 修复获取无法获取 packageName 的问题。
  • 修复无法指定 KeyGenerator 的问题。
  • 优化生成 StringFog.java 文件的任务逻辑。
  • 暂时移除 Mapping 文件生成逻辑,可能导致无法删除的问题。

v5.0.0

  • 支持 Gradle 8.0。

v4.0.1

  • 修复 Base64 API 版本兼容问题。

v4.0.0

  • 使用 ASM7 以支持 Android 12。
  • 支持 AGP(Android Gradle Plugin) 7.x 版本。
  • DSL 新增 StringFogMode 选项,用于控制字符串加密后在字节码中的存在形式,支持 base64 和 bytes 两种模式,默认使用 base64。
    • base64 模式:将字符串加密后的字节序列使用 base64 编码,行为同 1.x 和 2.x 版本。
    • bytes 模式:将字符串加密后的字节序列直接呈现在字节码中,行为同 3.x 版本。

v3.0.0

  • 密文不再以 String 形式存在,改为直接字节数组,感谢 PR #50。
  • 重构公开 API 相关代码(不兼容历史版本)。
  • 删除 AES 加密实现,考虑到存在 bug 和性能问题且意义不大。
  • xor 算法移除 base64 编码。
  • 固定加密字符串 key 改为随机 key,且提供 IKeyGenerator 接口支持自定义实现。
  • 插件依赖的 ASM 库由 5.x 升级到 9.2。

v2.2.1

  • 修复 module-info 类导致的报错问题

v2.2.0

  • 支持 AGP(Android Gradle Plugin) 3.3.0+版本

v2.1.0

  • 修复 kotlin 打包的 bug

v2.0.1

  • 增加 implementation 自定义算法实现类详细报错信息

v2.0.0

  • 修改 gradle 配置(必须配置 implementation 指定算法实现)。
  • 修复大字符串编译失败的问题。
  • 新增自定义加解密算法扩展。
  • 新增生成 mapping 映射表文件。

v1.4.1

  • 修复使用 Java 8 时出现的 ZipException 编译错误

v1.4.0

  • 新增指定包名加密的配置项:fogPackages
  • 移除指定包名不加密的配置项:exclude

v1.3.0

  • 修复 gradle 3.0+编译报错的 bug

v1.2.2

  • 修复 windows 下打包后报错的 bug

v1.2.1

  • 修复 windows 下文件分隔符的 bug
  • 修复 applicationId 和 packageName 不一致导致无法编译的 bug
  • 优化功能,不需要再手动 exclude 已使用 StringFog 的库

v1.2.0

  • 支持在 library 中使用,每个 library 可以使用不同 key
  • 支持 exclude 指定包名不进行加密
  • 修复一些已知 bug

Copyright (C) 2016-2023, Megatron King

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Apps
About Me
GitHub: Trinea
Facebook: Dev Tools