451 lines
16 KiB
C++
451 lines
16 KiB
C++
#pragma clang diagnostic push
|
||
#pragma ide diagnostic ignored "cppcoreguidelines-narrowing-conversions"
|
||
#pragma once
|
||
#include <cstdint>
|
||
#include <ctime>
|
||
#include <cstring>
|
||
#ifndef HEADER_JNI_H_
|
||
#define HEADER_JNI_H_
|
||
#include <jni.h>
|
||
#endif
|
||
#ifndef HEADER_P_H_
|
||
#define HEADER_P_H_
|
||
#include "guard/JByteArrayGuard.cpp"
|
||
#endif
|
||
#include <string>
|
||
|
||
// 字节序转换宏(跨平台)
|
||
#pragma clang diagnostic push
|
||
#pragma ide diagnostic ignored "UnreachableCallsOfFunction"
|
||
#if defined(_WIN32)
|
||
#include <winsock2.h>
|
||
#pragma commen+t(lib, "ws2_32.lib")
|
||
|
||
#define htobe32(x) htonl(x)
|
||
#define be32toh(x) ntohl(x)
|
||
#define htobe16(x) htons(x)
|
||
#define be16toh(x) ntohs(x)
|
||
|
||
// Windows下64位字节序转换需要自己实现
|
||
static inline uint64_t htobe64(uint64_t x) {
|
||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||
return ((uint64_t)htonl(x & 0xFFFFFFFF) << 32) | htonl(x >> 32);
|
||
#else
|
||
return x;
|
||
#endif
|
||
}
|
||
|
||
static inline uint64_t be64toh(uint64_t x) {
|
||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||
return ((uint64_t)ntohl(x & 0xFFFFFFFF) << 32) | ntohl(x >> 32);
|
||
#else
|
||
return x;
|
||
#endif
|
||
}
|
||
|
||
#elif defined(__APPLE__) || defined(__FreeBSD__)
|
||
#include <libkern/OSByteOrder.h>
|
||
#define htobe32(x) OSSwapHostToBigInt32(x)
|
||
#define be32toh(x) OSSwapBigToHostInt32(x)
|
||
#define htobe16(x) OSSwapHostToBigInt16(x)
|
||
#define be16toh(x) OSSwapBigToHostInt16(x)
|
||
#define htobe64(x) OSSwapHostToBigInt64(x)
|
||
#define be64toh(x) OSSwapBigToHostInt64(x)
|
||
|
||
#elif defined(__linux__) || defined(__ANDROID__)
|
||
#include <endian.h>
|
||
// Linux下endian.h已经定义了这些宏
|
||
|
||
#else
|
||
// 通用实现
|
||
#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||
// GCC/Clang内置函数
|
||
#define htobe32(x) __builtin_bswap32(x)
|
||
#define be32toh(x) __builtin_bswap32(x)
|
||
#define htobe16(x) __builtin_bswap16(x)
|
||
#define be16toh(x) __builtin_bswap16(x)
|
||
#define htobe64(x) __builtin_bswap64(x)
|
||
#define be64toh(x) __builtin_bswap64(x)
|
||
#else
|
||
#define htobe32(x) (x)
|
||
#define be32toh(x) (x)
|
||
#define htobe16(x) (x)
|
||
#define be16toh(x) (x)
|
||
#define htobe64(x) (x)
|
||
#define be64toh(x) (x)
|
||
#endif
|
||
#endif
|
||
|
||
// 手动字节序转换函数(备用)
|
||
static inline uint64_t manual_htobe64(uint64_t x) {
|
||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||
return ((uint64_t)__builtin_bswap32(x & 0xFFFFFFFF) << 32) | __builtin_bswap32(x >> 32);
|
||
#else
|
||
return x;
|
||
#endif
|
||
}
|
||
|
||
static inline uint64_t manual_be64toh(uint64_t x) {
|
||
return manual_htobe64(x); // 对称操作
|
||
}
|
||
|
||
namespace EnhancedEncryptionMagic {
|
||
// 主魔数:0x4C494233 (ASCII: "LIB3")
|
||
static const uint32_t MAGIC = 0x4C494233; // "LIB3" in hex
|
||
|
||
// 文件头结构 - 调整为实际大小
|
||
struct EnhancedFileHeader {
|
||
uint32_t magic; // 魔数: 0x4C494233 "LIB3" (4字节)
|
||
uint16_t version_major; // 主版本号 (2字节)
|
||
uint16_t version_minor; // 次版本号 (2字节)
|
||
uint32_t flags; // 标志位 (4字节)
|
||
uint32_t original_size; // 原始数据大小 (4字节)
|
||
uint32_t encrypted_size; // 加密数据大小 (4字节)
|
||
uint64_t timestamp; // 时间戳 (8字节)
|
||
uint32_t checksum; // 校验和 (4字节)
|
||
uint32_t reserved; // 保留字段 (4字节)
|
||
// 总计: 4+2+2+4+4+4+8+4+4 = 36字节
|
||
|
||
// 编译器可能添加4字节填充到40字节,但我们应该按36字节处理
|
||
};
|
||
|
||
// 计算实际结构体大小
|
||
static const size_t CALCULATED_HEADER_SIZE =
|
||
sizeof(uint32_t) + // magic
|
||
sizeof(uint16_t) + // version_major
|
||
sizeof(uint16_t) + // version_minor
|
||
sizeof(uint32_t) + // flags
|
||
sizeof(uint32_t) + // original_size
|
||
sizeof(uint32_t) + // encrypted_size
|
||
sizeof(uint64_t) + // timestamp
|
||
sizeof(uint32_t) + // checksum
|
||
sizeof(uint32_t); // reserved
|
||
|
||
static const size_t HEADER_SIZE = CALCULATED_HEADER_SIZE;
|
||
|
||
// 标志位定义
|
||
namespace Flags {
|
||
static const uint32_t COMPRESSED = 0x00000001; // 是否压缩
|
||
static const uint32_t SIGNED = 0x00000002; // 是否签名
|
||
static const uint32_t ENCRYPTED = 0x00000004; // 是否加密
|
||
static const uint32_t VALIDATED = 0x00000008; // 是否验证
|
||
};
|
||
|
||
// 创建文件头
|
||
static inline EnhancedFileHeader createHeader(uint32_t originalSize, uint32_t encryptedSize) {
|
||
EnhancedFileHeader header;
|
||
memset(&header, 0, sizeof(header)); // 清零初始化
|
||
|
||
header.magic = MAGIC;
|
||
header.version_major = 1;
|
||
header.version_minor = 0;
|
||
header.flags = Flags::ENCRYPTED;
|
||
header.original_size = originalSize;
|
||
header.encrypted_size = encryptedSize;
|
||
header.timestamp = static_cast<uint64_t>(time(nullptr));
|
||
header.checksum = 0; // 将在之后计算
|
||
header.reserved = 0;
|
||
|
||
return header;
|
||
}
|
||
|
||
// 字节序安全的内存复制函数
|
||
static inline void writeUint32(jbyte* buffer, uint32_t value, size_t offset) {
|
||
uint32_t networkValue = htobe32(value);
|
||
memcpy(buffer + offset, &networkValue, sizeof(uint32_t));
|
||
}
|
||
|
||
static inline void writeUint16(jbyte* buffer, uint16_t value, size_t offset) {
|
||
uint16_t networkValue = htobe16(value);
|
||
memcpy(buffer + offset, &networkValue, sizeof(uint16_t));
|
||
}
|
||
|
||
static inline void writeUint64(jbyte* buffer, uint64_t value, size_t offset) {
|
||
uint64_t networkValue = htobe64(value);
|
||
memcpy(buffer + offset, &networkValue, sizeof(uint64_t));
|
||
}
|
||
|
||
static inline uint32_t readUint32(const jbyte* buffer, size_t offset) {
|
||
uint32_t networkValue;
|
||
memcpy(&networkValue, buffer + offset, sizeof(uint32_t));
|
||
return be32toh(networkValue);
|
||
}
|
||
|
||
static inline uint16_t readUint16(const jbyte* buffer, size_t offset) {
|
||
uint16_t networkValue;
|
||
memcpy(&networkValue, buffer + offset, sizeof(uint16_t));
|
||
return be16toh(networkValue);
|
||
}
|
||
|
||
static inline uint64_t readUint64(const jbyte* buffer, size_t offset) {
|
||
uint64_t networkValue;
|
||
memcpy(&networkValue, buffer + offset, sizeof(uint64_t));
|
||
return be64toh(networkValue);
|
||
}
|
||
|
||
// 验证文件头
|
||
static inline bool validateHeader(const EnhancedFileHeader& header) {
|
||
return header.magic == MAGIC &&
|
||
header.version_major == 1 &&
|
||
header.version_minor == 0 &&
|
||
(header.flags & Flags::ENCRYPTED) != 0;
|
||
}
|
||
|
||
// 计算校验和(简单的CRC32替代)
|
||
static inline uint32_t calculateChecksum(const jbyte* data, jsize length) {
|
||
if (!data || length <= 0) {
|
||
return 0;
|
||
}
|
||
|
||
uint32_t crc = 0xFFFFFFFF;
|
||
const uint8_t* bytes = reinterpret_cast<const uint8_t*>(data);
|
||
|
||
for (jsize i = 0; i < length; i++) {
|
||
crc ^= bytes[i];
|
||
for (int j = 0; j < 8; j++) {
|
||
if (crc & 1) {
|
||
crc = (crc >> 1) ^ 0xEDB88320;
|
||
} else {
|
||
crc = crc >> 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
return ~crc;
|
||
}
|
||
|
||
// 更新文件头的校验和
|
||
static inline void updateChecksum(EnhancedFileHeader& header, const jbyte* data, jsize length) {
|
||
header.checksum = calculateChecksum(data, length);
|
||
}
|
||
|
||
// 验证数据校验和
|
||
static inline bool verifyChecksum(const EnhancedFileHeader& header, const jbyte* data, jsize length) {
|
||
uint32_t calculated = calculateChecksum(data, length);
|
||
return header.checksum == calculated;
|
||
}
|
||
|
||
// 将文件头写入字节数组(使用网络字节序)
|
||
static inline void writeHeaderToBytes(const EnhancedFileHeader& header, jbyte* buffer) {
|
||
if (!buffer) return;
|
||
|
||
size_t offset = 0;
|
||
writeUint32(buffer, header.magic, offset); offset += 4;
|
||
writeUint16(buffer, header.version_major, offset); offset += 2;
|
||
writeUint16(buffer, header.version_minor, offset); offset += 2;
|
||
writeUint32(buffer, header.flags, offset); offset += 4;
|
||
writeUint32(buffer, header.original_size, offset); offset += 4;
|
||
writeUint32(buffer, header.encrypted_size, offset); offset += 4;
|
||
writeUint64(buffer, header.timestamp, offset); offset += 8;
|
||
writeUint32(buffer, header.checksum, offset); offset += 4;
|
||
writeUint32(buffer, header.reserved, offset); offset += 4;
|
||
}
|
||
|
||
// 从字节数组读取文件头
|
||
static inline EnhancedFileHeader readHeaderFromBytes(const jbyte* buffer) {
|
||
EnhancedFileHeader header{};
|
||
memset(&header, 0, sizeof(header));
|
||
|
||
if (!buffer) return header;
|
||
|
||
size_t offset = 0;
|
||
header.magic = readUint32(buffer, offset); offset += 4;
|
||
header.version_major = readUint16(buffer, offset); offset += 2;
|
||
header.version_minor = readUint16(buffer, offset); offset += 2;
|
||
header.flags = readUint32(buffer, offset); offset += 4;
|
||
header.original_size = readUint32(buffer, offset); offset += 4;
|
||
header.encrypted_size = readUint32(buffer, offset); offset += 4;
|
||
header.timestamp = readUint64(buffer, offset); offset += 8;
|
||
header.checksum = readUint32(buffer, offset); offset += 4;
|
||
header.reserved = readUint32(buffer, offset); offset += 4;
|
||
|
||
return header;
|
||
}
|
||
|
||
// 将文件头格式化为可读字符串
|
||
static inline std::string headerToString(const EnhancedFileHeader& header) {
|
||
char magicStr[5] = {0};
|
||
memcpy(magicStr, &header.magic, 4);
|
||
|
||
char buffer[256];
|
||
snprintf(buffer, sizeof(buffer),
|
||
"Magic: %s (0x%08X)\n"
|
||
"Version: %d.%d\n"
|
||
"Flags: 0x%08X\n"
|
||
"Original Size: %u bytes\n"
|
||
"Encrypted Size: %u bytes\n"
|
||
"Timestamp: %llu\n"
|
||
"Checksum: 0x%08X\n"
|
||
"Reserved: 0x%08X",
|
||
magicStr, header.magic,
|
||
header.version_major, header.version_minor,
|
||
header.flags,
|
||
header.original_size,
|
||
header.encrypted_size,
|
||
(unsigned long long)header.timestamp,
|
||
header.checksum,
|
||
header.reserved);
|
||
|
||
return std::string(buffer);
|
||
}
|
||
|
||
// 验证文件是否完整
|
||
static inline bool validateFileIntegrity(const EnhancedFileHeader& header,
|
||
const jbyte* encryptedData,
|
||
jsize encryptedDataSize) {
|
||
// 检查大小是否匹配
|
||
if (header.encrypted_size != encryptedDataSize) {
|
||
return false;
|
||
}
|
||
|
||
// 检查校验和
|
||
return verifyChecksum(header, encryptedData, encryptedDataSize);
|
||
}
|
||
|
||
// 加密函数指针类型
|
||
typedef void (*EncryptFunc)(jbyte*, jsize, const char*, int);
|
||
|
||
// 创建完整的加密文件
|
||
static inline jbyteArray createEncryptedFile(JNIEnv* env,
|
||
const jbyte* originalData,
|
||
jsize originalSize,
|
||
const char* key,
|
||
size_t keyLen,
|
||
EncryptFunc encryptFunc) {
|
||
|
||
if (!env || !originalData || originalSize <= 0 || !key || keyLen <= 0 || !encryptFunc) {
|
||
return nullptr;
|
||
}
|
||
|
||
// 1. 创建加密数据数组
|
||
jbyteArray encryptedDataArray = env->NewByteArray(originalSize);
|
||
if (!encryptedDataArray) {
|
||
return nullptr;
|
||
}
|
||
|
||
{
|
||
// 使用局部作用域确保 encryptedDataGuard 在加密后释放
|
||
JByteArrayGuard encryptedDataGuard(env, encryptedDataArray, false, JNI_ABORT);
|
||
if (!encryptedDataGuard.isValid()) {
|
||
env->DeleteLocalRef(encryptedDataArray);
|
||
return nullptr;
|
||
}
|
||
|
||
// 复制并加密数据
|
||
memcpy(encryptedDataGuard.get(), originalData, originalSize);
|
||
encryptFunc(encryptedDataGuard.get(), originalSize, key, keyLen);
|
||
|
||
// encryptedDataGuard 析构函数会自动以 JNI_ABORT 模式释放
|
||
}
|
||
|
||
// 注意:这里已经释放了加密数据,需要重新获取
|
||
JByteArrayGuard encryptedDataGuard2(env, encryptedDataArray);
|
||
if (!encryptedDataGuard2.isValid()) {
|
||
env->DeleteLocalRef(encryptedDataArray);
|
||
return nullptr;
|
||
}
|
||
|
||
// 2. 创建文件头
|
||
EnhancedFileHeader header = createHeader(originalSize, originalSize);
|
||
updateChecksum(header, encryptedDataGuard2.get(), originalSize);
|
||
|
||
// 3. 创建最终结果
|
||
jsize totalSize = HEADER_SIZE + originalSize;
|
||
jbyteArray result = env->NewByteArray(totalSize);
|
||
if (!result) {
|
||
return nullptr;
|
||
}
|
||
|
||
JByteArrayGuard resultGuard(env, result);
|
||
if (!resultGuard.isValid()) {
|
||
env->DeleteLocalRef(result);
|
||
return nullptr;
|
||
}
|
||
|
||
// 4. 写入数据
|
||
writeHeaderToBytes(header, resultGuard.get());
|
||
memcpy(resultGuard.get() + HEADER_SIZE, encryptedDataGuard2.get(), originalSize);
|
||
|
||
// 5. 显式提交修改
|
||
resultGuard.commit(); // 提交修改到 Java 端
|
||
// resultGuard 析构时不会再释放
|
||
|
||
// 6. 清理中间数组
|
||
env->DeleteLocalRef(encryptedDataArray);
|
||
|
||
return result;
|
||
}
|
||
|
||
// 从加密文件中提取数据
|
||
static inline jbyteArray extractFromEncryptedFile(JNIEnv* env,
|
||
const jbyte* fileData,
|
||
jsize fileSize,
|
||
const char* key,
|
||
size_t keyLen,
|
||
EncryptFunc decryptFunc,
|
||
bool* isValid) {
|
||
|
||
if (isValid) *isValid = false;
|
||
|
||
if (!env || !fileData || fileSize < HEADER_SIZE || !key || keyLen <= 0 || !decryptFunc) {
|
||
return nullptr;
|
||
}
|
||
|
||
// 读取文件头
|
||
EnhancedFileHeader header = readHeaderFromBytes(fileData);
|
||
|
||
// 验证文件头
|
||
if (!validateHeader(header)) {
|
||
return nullptr;
|
||
}
|
||
|
||
// 检查文件大小
|
||
jsize expectedSize = HEADER_SIZE + header.encrypted_size;
|
||
if (fileSize != expectedSize) {
|
||
return nullptr;
|
||
}
|
||
|
||
// 提取加密数据
|
||
const jbyte* encryptedData = fileData + HEADER_SIZE;
|
||
|
||
// 验证完整性
|
||
if (!validateFileIntegrity(header, encryptedData, header.encrypted_size)) {
|
||
return nullptr;
|
||
}
|
||
|
||
// 创建结果数组
|
||
jbyteArray result = env->NewByteArray(header.original_size);
|
||
if (!result) {
|
||
return nullptr;
|
||
}
|
||
JByteArrayGuard resultDataGuard(env, result);
|
||
|
||
if (!resultDataGuard.isValid()) {
|
||
env->DeleteLocalRef(result);
|
||
return nullptr;
|
||
}
|
||
|
||
jbyte* resultData = resultDataGuard.get();
|
||
|
||
// 复制加密数据
|
||
memcpy(resultData, encryptedData, header.original_size);
|
||
|
||
// 解密数据
|
||
decryptFunc(resultData, header.original_size, key, keyLen);
|
||
|
||
if (isValid) *isValid = true;
|
||
return result;
|
||
}
|
||
|
||
// 验证是否为加密文件(不读取整个文件)
|
||
static inline bool isEncryptedFile(const jbyte* fileData, jsize fileSize) {
|
||
if (fileSize < HEADER_SIZE || !fileData) {
|
||
return false;
|
||
}
|
||
|
||
EnhancedFileHeader header = readHeaderFromBytes(fileData);
|
||
return validateHeader(header);
|
||
}
|
||
}
|
||
#pragma clang diagnostic pop
|
||
#pragma clang diagnostic pop |