我正在开发一个使用 AI 进行视频处理的原生 Java 应用程序。为了增强安全性,我想对 DEX 文件进行加密以防止逆向工程,并在设备上安全地加密和存储 AI 模型文件。我正在寻找易于实施的有效安全措施,最好是开源解决方案。除了网上提供的付费工具之外,还有其他推荐的方法吗?
混淆在一定程度上起到了作用,但大多数代码仍然对用户可见。并且模型文件需要加密
以下是如何实现 DEX 文件加密的指南:
加密DEX文件(打包前) 爪哇
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.SecureRandom;
public class DexEncryptor {
public static void main(String[] args) throws Exception {
String key = "1234567890123456"; // Use a secure key
File originalDexFile = new File("path_to_your_original_classes.dex");
File encryptedDexFile = new File("path_to_output_encrypted_classes.dex");
encryptFile(key.getBytes(), originalDexFile, encryptedDexFile);
}
public static void encryptFile(byte[] key, File inputFile, File outputFile) throws Exception {
Cipher cipher = Cipher.getInstance("AES");
SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
FileInputStream fis = new FileInputStream(inputFile);
byte[] inputBytes = new byte[(int) inputFile.length()];
fis.read(inputBytes);
byte[] outputBytes = cipher.doFinal(inputBytes);
FileOutputStream fos = new FileOutputStream(outputFile);
fos.write(outputBytes);
fis.close();
fos.close();
}
}
此代码将使用 AES 加密来加密classes.dex 文件。
运行时解密并加载加密的DEX 爪哇
import android.app.Application;
import dalvik.system.DexClassLoader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
try {
// Decrypt the DEX file
String key = "1234567890123456"; // Use the same key
InputStream encryptedDexInputStream = getAssets().open("encrypted_classes.dex"); // Place encrypted DEX in assets folder
byte[] encryptedBytes = new byte[encryptedDexInputStream.available()];
encryptedDexInputStream.read(encryptedBytes);
byte[] decryptedBytes = decryptBytes(encryptedBytes, key.getBytes());
// Save decrypted DEX to the app's internal storage
File dexFile = new File(getFilesDir(), "classes.dex");
FileOutputStream fos = new FileOutputStream(dexFile);
fos.write(decryptedBytes);
fos.close();
// Load the decrypted DEX file
String optimizedDir = getDir("dex", 0).getAbsolutePath();
DexClassLoader classLoader = new DexClassLoader(dexFile.getAbsolutePath(), optimizedDir, null, getClassLoader());
// Load classes if necessary (optional)
Class<?> clazz = classLoader.loadClass("com.example.MyClass");
Object obj = clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
private byte[] decryptBytes(byte[] encryptedBytes, byte[] key) throws Exception {
Cipher cipher = Cipher.getInstance("AES");
SecretKeySpec secretKey = new SecretKeySpec(key, "AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
return cipher.doFinal(encryptedBytes);
}
}
使用 ProGuard 或 R8 等工具混淆密钥。 使用NDK(本机开发工具包)来处理本机代码(C/C++)中的解密。 使用基于服务器的密钥管理来安全地获取解密密钥。 将密钥拆分到应用程序的不同部分并动态组装它。 4. 混淆并缩小你的代码 使用 ProGuard 或 R8 来混淆和缩小代码:
将以下内容添加到您的 proguard-rules.pro 文件中:
proguard
-keep class com.example.MyApplication { *; }
-keepclassmembers class ** {
public <init>(...);
}
-keepattributes *Annotation*
-dontwarn dalvik.system.DexClassLoader