uni-app apk加固的assets资源文件加密sqlite文件问题:取出包内的sqlite文件,用数据库查询工具仍可以正常访问

uni-app apk加固的assets资源文件加密sqlite文件问题:取出包内的sqlite文件,用数据库查询工具仍可以正常访问

操作步骤:

  • 加固,assets资源文件加密

预期结果:

  • 加固后取出包内的db文件,不能正常访问。

实际结果:

  • 加固后取出包内的db文件,能正常访问。

bug描述:

  • 加固apk的assets的资源的sqlite DB文件,不过把db文件的扩展名给取了。加固后取出包内的db文件,可以正常访问。
1 回复

更多关于uni-app apk加固的assets资源文件加密sqlite文件问题:取出包内的sqlite文件,用数据库查询工具仍可以正常访问的实战教程也可以访问 https://www.itying.com/category-93-b0.html


在使用 uni-app 开发应用时,可能会遇到需要对 assets 目录中的 SQLite 数据库文件进行加密的需求,以防止打包后的 APK 文件被轻易解压并访问其中的数据库内容。如果直接解压 APK 文件并取出 SQLite 文件,使用数据库查询工具仍然可以正常访问,说明 SQLite 文件没有进行加密或保护。

解决方案

以下是一些常见的解决方案,用于加密或保护 assets 目录中的 SQLite 文件:

1. 加密 SQLite 文件

在打包 APK 之前,可以对 assets 目录中的 SQLite 文件进行加密。然后在应用启动时,动态解密并复制到应用的私有目录中。

步骤:

  1. 使用加密算法(如 AES)对 SQLite 文件进行加密,生成加密后的文件。
  2. 将加密后的文件放入 assets 目录。
  3. 在应用启动时,读取加密文件并解密,然后将解密后的文件保存到应用的私有目录中。
  4. 应用运行时,使用解密后的 SQLite 文件进行数据库操作。

示例代码:

const fs = require('fs');
const crypto = require('crypto');

// 加密函数
function encryptFile(inputFile, outputFile, key) {
    const cipher = crypto.createCipher('aes-256-cbc', key);
    const input = fs.createReadStream(inputFile);
    const output = fs.createWriteStream(outputFile);
    
    input.pipe(cipher).pipe(output);
}

// 解密函数
function decryptFile(inputFile, outputFile, key) {
    const decipher = crypto.createDecipher('aes-256-cbc', key);
    const input = fs.createReadStream(inputFile);
    const output = fs.createWriteStream(outputFile);
    
    input.pipe(decipher).pipe(output);
}

// 加密 assets 中的 SQLite 文件
encryptFile('assets/original.db', 'assets/encrypted.db', 'your-secret-key');

在应用中解密:

import { plus } from 'uni-program';

// 解密并复制到私有目录
function decryptDatabase() {
    const filePath = plus.io.convertLocalFileSystemURL('_www/assets/encrypted.db');
    const key = 'your-secret-key';
    const decryptedPath = plus.io.convertLocalFileSystemURL('_doc/decrypted.db');
    
    // 读取加密文件
    plus.io.resolveLocalFileSystemURL(filePath, function(entry) {
        entry.file(function(file) {
            const reader = new FileReader();
            reader.onload = function(e) {
                const encryptedData = e.target.result;
                
                // 解密数据
                const decipher = crypto.createDecipher('aes-256-cbc', key);
                let decryptedData = decipher.update(encryptedData, 'binary', 'binary');
                decryptedData += decipher.final('binary');
                
                // 写入解密后的文件
                const blob = new Blob([decryptedData], { type: 'application/octet-stream' });
                plus.io.resolveLocalFileSystemURL(decryptedPath, function(fileEntry) {
                    fileEntry.createWriter(function(writer) {
                        writer.write(blob);
                    });
                });
            };
            reader.readAsBinaryString(file);
        });
    });
}

2. 使用 SQLCipher 加密数据库

SQLCipher 是 SQLite 的一个扩展,提供了透明的 256 位 AES 数据库文件加密。你可以在应用中使用 SQLCipher 来加密 SQLite 数据库。

步骤:

  1. 在应用中集成 SQLCipher。
  2. 在应用启动时,使用 SQLCipher 打开数据库并设置密码。
  3. 在应用运行时,使用 SQLCipher 进行数据库操作。

集成 SQLCipher:

示例代码:

import SQLite from 'react-native-sqlite-storage';

// 打开加密数据库
const db = SQLite.openDatabase({ name: 'encrypted.db', location: 'default', key: 'your-secret-key' }, () => {
    console.log('Database opened');
}, (err) => {
    console.error('Failed to open database', err);
});

3. 使用自定义文件格式

将 SQLite 文件转换为自定义的文件格式,并在应用启动时将其转换回 SQLite 文件。

步骤:

  1. 将 SQLite 文件转换为自定义格式(如二进制格式或其他加密格式)。
  2. 将转换后的文件放入 assets 目录。
  3. 在应用启动时,读取自定义格式的文件并转换回 SQLite 文件,保存到应用的私有目录中。
  4. 应用运行时,使用转换后的 SQLite 文件进行数据库操作。

示例代码:

// 转换 SQLite 文件为自定义格式
function convertToCustomFormat(inputFile, outputFile) {
    const data = fs.readFileSync(inputFile);
    // 自定义转换逻辑
    const customData = customLogic(data);
    fs.writeFileSync(outputFile, customData);
}

// 转换回 SQLite 文件
function convertToSQLite(inputFile, outputFile) {
    const customData = fs.readFileSync(inputFile);
    // 自定义转换逻辑
    const sqliteData = customLogic(customData);
    fs.writeFileSync(outputFile, sqliteData);
}

在应用中转换:

import { plus } from 'uni-program';

// 转换并复制到私有目录
function convertDatabase() {
    const filePath = plus.io.convertLocalFileSystemURL('_www/assets/custom.db');
    const convertedPath = plus.io.convertLocalFileSystemURL('_doc/original.db');
    
    // 读取自定义格式文件
    plus.io.resolveLocalFileSystemURL(filePath, function(entry) {
        entry.file(function(file) {
            const reader = new FileReader();
            reader.onload = function(e) {
                const customData = e.target.result;
                
                // 转换回 SQLite 文件
                const sqliteData = customLogic(customData);
                
                // 写入转换后的文件
                const blob = new Blob([sqliteData], { type: 'application/octet-stream' });
                plus.io.resolveLocalFileSystemURL(convertedPath, function(fileEntry) {
                    fileEntry.createWriter(function(writer) {
                        writer.write(blob);
                    });
                });
            };
            reader.readAsBinaryString(file);
        });
    });
}
回到顶部