【干货分享】uniapp做的安卓App如何加固
2023年了,uniapp还有人用吗?
对于这个问题,只能说,2023年了,使用uniapp去开发APP的人越来越多了。
一方面在于全平台兼容确实很香,对于一些小项目或者时间要求比较高的项目来说,可以节省大量的时间与精力,也为公司节约了成本;另一方面,开发速度非常快。就像前面说的,对于一些小项目来说,几天就可以搞定,而对于一些大项目来说,性能和原生大差不差,而且全平台兼容的特性也可以弥补这点;最后就是社区,里面有很多优质的框架和插件,节约了大量的时间(时间就是发量!!!),更重要的是,社区出人才,总能找到人和你一起吐槽(bushi)睿智的官方......
总而言之,虽然uniapp文档一般好,bug一般多,更新像拆炸弹,但是,对于很多人来说,还是很有意义的。所以用的人还是很多。
但是目前随着各种商城上架政策的严格审查,对于加固等需求也慢慢起来了,所以今天我们来讲讲uniapp开发的安卓APP要如何加固。
加固原理
先来看看一般加固会从哪几个方向进行加固
而我们如果把uniapp制作的安卓APP在加固上其实大同小异--只要是apk或者aab格式都可以,所以我们就基于这个原理来进行加固。
加固流程
01 代码混淆
按照一般的思路,先给他混淆一下子。使用代码混淆工具来混淆 JavaScript 代码,以使其难以被逆向工程和破解。常用的混淆工具包括 ProGuard 和 DexGuard。在 UniApp 中,你可以在打包安卓应用时配置 ProGuard 来进行代码混淆。示例代码如下所示,在项目根目录下的 uniapp.pro
文件中添加以下配置:
-keep class com.dcloud.** { *; }
-keep public class * extends io.dcloud.* {
*;
}
02 加固资源文件 & 防止调试和反调试
加固资源文件: 将敏感资源文件(如证书、配置文件等)进行加密或混淆,以防止被攻击者获取。可以使用第三方工具对资源文件进行加密,或者自定义加密算法来保护资源文件的安全
防止调试和反调试: 这一步可以使用第三方库或自定义代码来实现这些保护措施。比如说,可以检测应用程序是否在调试模式下运行,并在调试模式下采取相应的措施,例如关闭应用程序或隐藏敏感信息。
import android.os.Debug;
public class DebugUtils {
public static boolean isDebugMode() {
return Debug.isDebuggerConnected();
}
}
就是说,在应用程序中调用 DebugUtils.isDebugMode()
方法,可以根据返回值来判断应用程序是否在调试模式下运行,并采取相应的措施。
03 加密敏感数据
我们直接使用PBEWithMD5AndDES 算法对数据进行加密和解密。使用的时候,你可以调用 EncryptionUtils.encrypt(data)
方法来加密敏感数据,并调用 EncryptionUtils.decrypt(encryptedData)
方法来解密数据。记得将 PASSWORD
和 SALT
替换为你自己的密码和盐值(重要!!!)。
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import java.security.spec.KeySpec;
import java.util.Base64;
public class EncryptionUtils {
private static final String ALGORITHM = "PBEWithMD5AndDES";
private static final String PASSWORD = "your_secret_password"; // 自定义密码,请更换为自己的密码
private static final byte[] SALT = {
(byte) 0x4b, (byte) 0x6d, (byte) 0x7d, (byte) 0x15,
(byte) 0x78, (byte) 0x56, (byte) 0x34, (byte) 0x22
}; // 自定义盐值,请更换为自己的盐值
public static String encrypt(String data) {
try {
KeySpec keySpec = new PBEKeySpec(PASSWORD.toCharArray(), SALT, 65536);
SecretKey secretKey = SecretKeyFactory.getInstance(ALGORITHM).generateSecret(keySpec);
Cipher cipher = Cipher.getInstance(ALGORITHM);
PBEParameterSpec parameterSpec = new PBEParameterSpec(SALT, 100);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, parameterSpec);
byte[] encryptedBytes = cipher.doFinal(data.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(encryptedBytes);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String decrypt(String encryptedData) {
try {
KeySpec keySpec = new PBEKeySpec(PASSWORD.toCharArray(), SALT, 65536);
SecretKey secretKey = SecretKeyFactory.getInstance(ALGORITHM).generateSecret(keySpec);
Cipher cipher = Cipher.getInstance(ALGORITHM);
PBEParameterSpec parameterSpec = new PBEParameterSpec(SALT, 100);
cipher.init(Cipher.DECRYPT_MODE, secretKey, parameterSpec);
byte[] decodedBytes = Base64.getDecoder().decode(encryptedData);
byte[] decryptedBytes = cipher.doFinal(decodedBytes);
return new String(decryptedBytes, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
04 防止篡改
我们使用 SHA-256 哈希算法计算数据的哈希值。使用的时候,可以调用 IntegrityUtils.calculateHash(data)
方法来计算数据的哈希值,并将其与原始的哈希值进行比较,以验证数据的完整性。例如:
String data = "Hello, world!";
String originalHash = "2ef7bde608ce5404e97d5f042f95f89f1c232871";
String calculatedHash = IntegrityUtils.calculateHash(data);
boolean isIntegrityVerified = IntegrityUtils.verifyIntegrity(data, originalHash);
if (isIntegrityVerified) {
System.out.println("Data integrity verified.");
} else {
System.out.println("Data has been tampered with!");
}
05 签名功能
补充一个Android签名。
1)简介
本工具用于对android加固后的apk进行重新签名。
版本 | 文件 | 备注 |
---|---|---|
Windows版 | apk签名工具压缩包.exe | 该版本包含Java运行环境,不需要额外安装。 |
通用版 | dx-signer-v1.9r.jar | 该版本需要Java 8+的运行环境,请依照操作系统进行安装:Adoptium。 |
本工具依照Apache 2.0
协议开源,可以在这里查看源码github.com/dingxiangte…。
使用说明
- 下载签名工具dx-signer.jar,双击运行。
- 选择输入apk、aab文件。
- 选择签名的key文件,并输入key密码。
- 选择重签后apk、aab的路径,以apk结束。如:D:\sign.apk
- 点击“签名”按钮,等待即可签名完成。
ps:如果有alias(证书别名)密钥的或者有多个证书的,请在高级tab中选择alias并输入alias密码
2)多渠道功能简介
多渠道工具兼容友盟和美团walle风格的多渠道包,方便客户把APP发布到不同的应用平台,进行渠道统计。
使用说明
- 在app中预留读取渠道信息的入口,具体见5.2.2读取渠道信息
- 在5.1.1的签名使用基础上,点击选择渠道清单
- 选择清单文件channel.txt。具体文件格式见5.2.3
- 点击签名,等待生成多个带签名的渠道app
读取渠道信息
顶象多渠道工具兼容友盟和美团walle风格的多渠道包,下面是两种不同风格的渠道信息读取方法。选其中之一即可
读取渠道信息:UMENG_CHANNEL
输出的Apk中将会包含UMENG_CHANNEL
的mata-data
name="UMENG_CHANNEL"
android:value="XXX" />
可以读取这个字段。
public static String getChannel(Context ctx) {
String channel = "";
try {
ApplicationInfo appInfo = ctx.getPackageManager().getApplicationInfo(ctx.getPackageName(),
PackageManager.GET_META_DATA);
channel = appInfo.metaData.getString("UMENG_CHANNEL");
} catch (PackageManager.NameNotFoundException ignore) {
}
return channel;
}
读取渠道信息:Walle
输出的Apk也包含Walle风格的渠道信息
可以在使用Walle的方式进行读取。
implementation 'com.meituan.android.walle:library:1.1.7'
String channel = WalleChannelReader.getChannel(this.getApplicationContext());
渠道文件格式说明
请准备渠道清单文件channel.txt
, 格式为每一行一个渠道, 例如:
0001_my
0003_baidu
0004_huawei
0005_oppo
0006_vivo
结语
以上就是基于uniapp制作的Android APP的加固方式,仅供参考~ 欢迎一起交流学习~
来源:juejin.cn/post/7256615625882615866