| | |
| | | #include <android/log.h> |
| | | #include <string.h> |
| | | #include <jni.h> |
| | | #include <sstream> |
| | | #include <iomanip> |
| | | |
| | | static jclass contextClass; |
| | | static jclass signatureClass; |
| | | static jclass packageNameClass; |
| | | static jclass packageInfoClass; |
| | | // 声明全局静态变量,用于存储Java类的引用 |
| | | static jclass contextClass; // Android Context类的引用 |
| | | static jclass signatureClass; // Android Signature类的引用 |
| | | static jclass packageNameClass; // Android PackageManager类的引用 |
| | | static jclass packageInfoClass; // Android PackageInfo类的引用 |
| | | |
| | | // 定义发布版本的签名常量 |
| | | const char *RELEASE_SIGN = "308202b8308201a0020101300d06092a864886f70d01010b05003022310f300d06035504030c06e5a4a7e7a6b9310f300d06035504070c06e5a4a9e6b4a5301e170d3233313132303035333131325a170d3438313131333035333131325a3022310f300d06035504030c06e5a4a7e7a6b9310f300d06035504070c06e5a4a9e6b4a530820122300d06092a864886f70d01010105000382010f003082010a0282010100a0924f3d618e4a622def691e16e54ce5bdfd035bd73e7cb947d2bf3bd0c00afa26e52963e0299fc06d76d153be696c5285d630577e1dcb2b740a72b6d904482217de308fb91c8435441ed05e844ced1e5c3446d82cb8f38751049df26a42adcfc33f1f12c2ce03f676e5d148aad800ace89670b87835e2c02a8570a0b6740d9c0669d4cb3c597d0b2dd49fc0904e885773b6d3a87d9f1e73eb526e0d1a9e9e3c48d986938286cd824151b5a6214faf89d3e699524511b23c86d3b110a7f0bb56a6d2436f69816538a62a38cb1fee6eb685d267cc200df8af51b936bd280beaa2023f75678d77a11ac6de734b30af63d394c8b63bccf2115a47ea15c9212c740d0203010001300d06092a864886f70d01010b05000382010100307cafa9b14be91ba6424cfcc6aed75b069a1c4d6eb646eab0de93f372f236f5f0a6097499df99391075d6ced18d419a2b15adb041890e2b56a3bfbd6be40efee99c5c713ba8ea1d45da09b67916106116e96eb735271c4d53e0739f753145cbc42e149ad3d9507d422ec1c6f1a7f792a4542f9a64f0de3d4f4af69f0fb3390ef3577dcf8844cf744426d173b0934d879148062c5ca64022dc99af370dbfeaf2b5d4a279b20c54a361bca12c25bf185c2885519bbbc36e46ddb083080f0cc5b1f2eafe964ebce5071b0ae7d92a34a9193861b996d2c0299b1993f41063a27038199365a6e3cb27a02ffa9facdc48a63713eb5fbf90e9fd73056aba16b28e5fee"; |
| | | |
| | | // 定义XOR加密密钥数组 |
| | | const unsigned char XOR_KEY[] = {0x7A, 0xB3, 0xC9, 0x7B, 0xE3, 0x78}; // 修改后三个字节的密钥 |
| | | |
| | | // 加密密钥 |
| | | const unsigned char XOR_KEY[] = {0x7A, 0xB3, 0xC9, 0xD5, 0xE1, 0xF8, 0x42, 0x91, 0x37, 0x8F, 0x5D, |
| | | 0x2E}; |
| | | // 定义后半部分XOR密钥数组 |
| | | const unsigned char XOR_KEY_BACK[] = {0x4D, 0xE4, 0x7C, 0x2A, 0x8B, 0x7F}; |
| | | |
| | | // 加密后的M1卡密码数组 |
| | | // 定义加密后的M1卡扇区密钥数组 |
| | | const unsigned char ENCRYPTED_SECTOR_KEYS[] = { |
| | | // 扇区0密码 (加密后) |
| | | 0x9C, 0x45, 0x36, 0x55, 0x8C, 0x7F, 0x35, 0x93, 0x4B, 0x78, 0x2A, 0x79, |
| | | // 扇区1密码 (加密后) |
| | | 0xB4, 0x52, 0x91, 0x45, 0x99, 0x87, 0x3C, 0xA3, 0x6E, 0x5F, 0x1D, 0x5E, |
| | | // 以下类似格式存储其他扇区密码... |
| | | 0x1E, 0x85, 0xEB, 0x51, 0xB9, 0x39, 0x02, 0x2E, 0x77, 0x1F, 0x3E, 0x93, |
| | | 0x22, 0x62, 0xBD, 0x83, 0x99, 0x2A, 0x2F, 0x19, 0x95, 0x07, 0x29, 0x2E, |
| | | 0x90, 0x18, 0xE0, 0x6A, 0xB7, 0x68, 0x34, 0x89, 0x42, 0x5B, 0x16, 0x47, |
| | | 0xA8, 0x0B, 0xB5, 0x97, 0xB4, 0x43, 0x1D, 0x62, 0x89, 0x73, 0x33, 0x2E, |
| | | 0x24, 0x9D, 0xB7, 0x46, 0x8D, 0x64, 0x49, 0x7A, 0x52, 0x41, 0x1C, 0x91, |
| | | 0x31, 0x78, 0x95, 0x52, 0x95, 0x39, 0x19, 0x4C, 0x81, 0x2A, 0x0D, 0x47, |
| | | 0xF5, 0x64, 0xA7, 0x93, 0xB9, 0x51, 0x27, 0x82, 0x43, 0x68, 0x31, 0x3F, |
| | | 0x55, 0x93, 0xB7, 0x68, 0x97, 0x9A, 0x37, 0x71, 0x52, 0x49, 0x17, 0x1E, |
| | | 0x8E, 0x93, 0xB5, 0x44, 0x8D, 0x42, 0x22, 0x84, 0x95, 0x33, 0x22, 0x93, |
| | | 0x42, 0x82, 0xA3, 0x35, 0x91, 0x33, 0x13, 0x93, 0x71, 0x21, 0x01, 0x71, |
| | | 0x37, 0x9F, 0xA6, 0x68, 0x92, 0x86, 0x46, 0x72, 0x43, 0x62, 0x12, 0x52, |
| | | 0x5D, 0x85, 0x93, 0x86, 0x82, 0x46, 0x31, 0x86, 0x57, 0x48, 0x16, 0x88, |
| | | 0x97, 0x73, 0xB5, 0x47, 0x95, 0x55, 0x36, 0x69, 0x49, 0x58, 0x18, 0x6A, |
| | | 0xEA, 0x46, 0x84, 0x93, 0x82, 0x19, 0x29, 0x91, 0x31, 0x1C, 0x0C, 0x7D |
| | | // 扇区0密码 (加密后) |
| | | 0x9C, 0x45, 0x36, 0x55, 0x8C, 0x7F, 0x35, 0x93, 0x4B, 0x78, 0x2A, 0x79, |
| | | // 扇区1密码 (加密后) |
| | | 0xB4, 0x52, 0x91, 0x45, 0x99, 0x87, 0x3C, 0xA3, 0x6E, 0x5F, 0x1D, 0x5E, |
| | | // 以下类似格式存储其他扇区密码... |
| | | 0x1E, 0x85, 0xEB, 0x51, 0xB9, 0x39, 0x02, 0x2E, 0x77, 0x1F, 0x3E, 0x93, |
| | | 0x22, 0x62, 0xBD, 0x83, 0x99, 0x2A, 0x2F, 0x19, 0x95, 0x07, 0x29, 0x2E, |
| | | 0x90, 0x18, 0xE0, 0x6A, 0xB7, 0x68, 0x34, 0x89, 0x42, 0x5B, 0x16, 0x47, |
| | | 0xA8, 0x0B, 0xB5, 0x97, 0xB4, 0x43, 0x1D, 0x62, 0x89, 0x73, 0x33, 0x2E, |
| | | 0x24, 0x9D, 0xB7, 0x46, 0x8D, 0x64, 0x49, 0x7A, 0x52, 0x41, 0x1C, 0x91, |
| | | 0x31, 0x78, 0x95, 0x52, 0x95, 0x39, 0x19, 0x4C, 0x81, 0x2A, 0x0D, 0x47, |
| | | 0xF5, 0x64, 0xA7, 0x93, 0xB9, 0x51, 0x27, 0x82, 0x43, 0x68, 0x31, 0x3F, |
| | | 0x55, 0x93, 0xB7, 0x68, 0x97, 0x9A, 0x37, 0x71, 0x52, 0x49, 0x17, 0x1E, |
| | | 0x8E, 0x93, 0xB5, 0x44, 0x8D, 0x42, 0x22, 0x84, 0x95, 0x33, 0x22, 0x93, |
| | | 0x42, 0x82, 0xA3, 0x35, 0x91, 0x33, 0x13, 0x93, 0x71, 0x21, 0x01, 0x71, |
| | | 0x37, 0x9F, 0xA6, 0x68, 0x92, 0x86, 0x46, 0x72, 0x43, 0x62, 0x12, 0x52, |
| | | 0x5D, 0x85, 0x93, 0x86, 0x82, 0x46, 0x31, 0x86, 0x57, 0x48, 0x16, 0x88, |
| | | 0x97, 0x73, 0xB5, 0x47, 0x95, 0x55, 0x36, 0x69, 0x49, 0x58, 0x18, 0x6A, |
| | | 0xEA, 0x46, 0x84, 0x93, 0x82, 0x19, 0x29, 0x91, 0x31, 0x1C, 0x0C, 0x7D |
| | | }; |
| | | |
| | | // 解密函数 |
| | | void decrypt_key(const unsigned char *encrypted, char *decrypted, size_t len) { |
| | | // 将字节数组转换为十六进制字符串的函数 |
| | | std::string bytesToHexString(const unsigned char* data, size_t len) { |
| | | std::stringstream ss; // 创建字符串流对象 |
| | | ss << std::hex << std::uppercase << std::setfill('0'); // 设置输出格式为十六进制,大写,不足两位补0 |
| | | for (size_t i = 0; i < len; i++) { |
| | | decrypted[i] = encrypted[i] ^ XOR_KEY[i % sizeof(XOR_KEY)]; |
| | | ss << std::setw(2) << static_cast<int>(data[i]); // 将每个字节转换为两位十六进制 |
| | | } |
| | | decrypted[len] = '\0'; |
| | | return ss.str(); // 返回转换后的字符串 |
| | | } |
| | | |
| | | //extern "C" JNIEXPORT jstring |
| | | // |
| | | //JNICALL |
| | | //Java_com_yglx_testjni_MainActivity_getKey( |
| | | // JNIEnv *env, |
| | | // jobject /* this */) { |
| | | // return env->NewStringUTF(AUTH_KEY); |
| | | //} |
| | | // 解密函数:使用XOR密钥解密数据 |
| | | jstring decrypt_key(JNIEnv* env, const unsigned char* encrypted_data, int length) { |
| | | if (!encrypted_data || length < 6) { |
| | | __android_log_print(ANDROID_LOG_ERROR, "GeBaseHelper", "Invalid input data"); |
| | | return nullptr; |
| | | } |
| | | |
| | | // 为不同扇区使用不同的XOR密钥 |
| | | const unsigned char XOR_KEYS[16][6] = { |
| | | {0x7A, 0xB3, 0xC9, 0x72, 0xFC, 0x78}, // 扇区0 |
| | | {0x7A, 0xB3, 0xC9, 0x5A, 0x05, 0xB7}, // 扇区1 |
| | | {0x7A, 0xB3, 0x63, 0x10, 0xF9, 0xA4}, // 扇区2 |
| | | {0x7A, 0x73, 0x35, 0xD1, 0xFE, 0x71}, // 扇区3 - 修改第3个字节 |
| | | {0x2A, 0x93, 0xF8, 0x13, 0xB1, 0x31}, // 扇区4 |
| | | {0x7A, 0xB3, 0x79, 0x6D, 0x40, 0x18}, // 扇区5 |
| | | {0x7A, 0xB1, 0x19, 0xDA, 0xD6, 0x9A}, // 扇区6 |
| | | {0x7A, 0x13, 0xDD, 0x63, 0x3E, 0x63}, // 扇区7 |
| | | {0x7A, 0x73, 0x71, 0x5D, 0x89, 0x11}, // 扇区8 |
| | | {0x7A, 0x73, 0xF1, 0xE2, 0xFF, 0xB1}, // 扇区9 |
| | | {0x7A, 0x6D, 0xE9, 0x42, 0xBE, 0xA0}, // 扇区10 |
| | | {0x7A, 0x43, 0xB1, 0x78, 0x76, 0x3D}, // 扇区11 |
| | | {0x79, 0x43, 0xD1, 0xD1, 0x70, 0xEB}, // 扇区12 |
| | | {0x7A, 0xB3, 0xBF, 0x49, 0x6B, 0xB1}, // 扇区13 |
| | | {0x2B, 0xA3, 0xB3, 0x00, 0x19, 0x2C}, // 扇区14 |
| | | {0x7A, 0xF3, 0xDA, 0x8B, 0x98, 0x15} // 扇区15 |
| | | }; |
| | | |
| | | // 获取当前扇区号 |
| | | int sector = -1; |
| | | for (int i = 0; i < 16; i++) { |
| | | if (memcmp(encrypted_data, &ENCRYPTED_SECTOR_KEYS[i * 12], 6) == 0) { |
| | | sector = i; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (sector == -1) { |
| | | __android_log_print(ANDROID_LOG_ERROR, "GeBaseHelper", "Unknown sector"); |
| | | return nullptr; |
| | | } |
| | | |
| | | // __android_log_print(ANDROID_LOG_INFO, "GeBaseHelper", "Decrypting sector %d", sector); |
| | | // __android_log_print(ANDROID_LOG_INFO, "GeBaseHelper", "Encrypted data: %02X %02X %02X %02X %02X %02X", |
| | | // encrypted_data[0], encrypted_data[1], encrypted_data[2], |
| | | // encrypted_data[3], encrypted_data[4], encrypted_data[5]); |
| | | // __android_log_print(ANDROID_LOG_INFO, "GeBaseHelper", "Using XOR key: %02X %02X %02X %02X %02X %02X", |
| | | // XOR_KEYS[sector][0], XOR_KEYS[sector][1], XOR_KEYS[sector][2], |
| | | // XOR_KEYS[sector][3], XOR_KEYS[sector][4], XOR_KEYS[sector][5]); |
| | | |
| | | unsigned char decrypted[6]; |
| | | for (int i = 0; i < 6; i++) { |
| | | decrypted[i] = encrypted_data[i] ^ XOR_KEYS[sector][i]; |
| | | // __android_log_print(ANDROID_LOG_INFO, "GeBaseHelper", "Byte %d: %02X ^ %02X = %02X", |
| | | // i, encrypted_data[i], XOR_KEYS[sector][i], decrypted[i]); |
| | | } |
| | | |
| | | std::string result; |
| | | result.reserve(13); // 6 bytes * 2 chars + null terminator |
| | | char hex[3]; |
| | | for (int i = 0; i < 6; i++) { |
| | | snprintf(hex, sizeof(hex), "%02X", decrypted[i]); |
| | | result += hex; |
| | | } |
| | | |
| | | // __android_log_print(ANDROID_LOG_INFO, "GeBaseHelper", "Decrypted result: %s", result.c_str()); |
| | | return env->NewStringUTF(result.c_str()); |
| | | } |
| | | |
| | | // JNI库加载时的初始化函数 |
| | | JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { |
| | | |
| | | JNIEnv *env = NULL; |
| | | jint result = -1; |
| | | JNIEnv *env = NULL; // 声明JNI环境指针 |
| | | jint result = -1; // 初始化返回值为错误状态 |
| | | // 获取JNI环境 |
| | | if (vm->GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK) |
| | | return result; |
| | | |
| | | // 获取并保存Java类的全局引用 |
| | | contextClass = (jclass) env->NewGlobalRef((env)->FindClass("android/content/Context")); |
| | | signatureClass = (jclass) env->NewGlobalRef((env)->FindClass("android/content/pm/Signature")); |
| | | packageNameClass = (jclass) env->NewGlobalRef( |
| | |
| | | packageInfoClass = (jclass) env->NewGlobalRef( |
| | | (env)->FindClass("android/content/pm/PackageInfo")); |
| | | |
| | | __android_log_print(ANDROID_LOG_DEBUG, "jw", "sss"); |
| | | return JNI_VERSION_1_4; |
| | | __android_log_print(ANDROID_LOG_DEBUG, "M1Card", "JNI_OnLoad completed"); // 输出初始化完成日志 |
| | | return JNI_VERSION_1_4; // 返回JNI版本 |
| | | } |
| | | |
| | | |
| | | // 获取M1卡扇区密钥的JNI函数 |
| | | extern "C" |
| | | JNIEXPORT jstring JNICALL |
| | | Java_com_dayu_general_tool_GeBaseHelper_getM1SectorKeySecure(JNIEnv *env, jobject instance, |
| | | jobject contextObject, |
| | | jint sectorIndex) { |
| | | // 参数有效性检查 |
| | | if (!contextObject || !env) { |
| | | __android_log_print(ANDROID_LOG_ERROR, "M1Card", "Invalid parameters"); |
| | | return env->NewStringUTF(""); |
| | | } |
| | | |
| | | // 获取包管理器相关方法ID |
| | | jmethodID getPackageManagerId = (env)->GetMethodID(contextClass, "getPackageManager", |
| | | "()Landroid/content/pm/PackageManager;"); |
| | | jmethodID getPackageNameId = (env)->GetMethodID(contextClass, "getPackageName", |
| | | "()Ljava/lang/String;"); |
| | | jmethodID signToStringId = (env)->GetMethodID(signatureClass, "toCharsString", |
| | | "()Ljava/lang/String;"); |
| | | jmethodID getPackageInfoId = (env)->GetMethodID(packageNameClass, "getPackageInfo", |
| | | "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;"); |
| | | jmethodID getPackageManagerId = env->GetMethodID(contextClass, "getPackageManager", |
| | | "()Landroid/content/pm/PackageManager;"); |
| | | jmethodID getPackageNameId = env->GetMethodID(contextClass, "getPackageName", |
| | | "()Ljava/lang/String;"); |
| | | jmethodID signToStringId = env->GetMethodID(signatureClass, "toCharsString", |
| | | "()Ljava/lang/String;"); |
| | | jmethodID getPackageInfoId = env->GetMethodID(packageNameClass, "getPackageInfo", |
| | | "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;"); |
| | | |
| | | // 检查方法ID获取是否成功 |
| | | if (!getPackageManagerId || !getPackageNameId || !signToStringId || !getPackageInfoId) { |
| | | __android_log_print(ANDROID_LOG_ERROR, "M1Card", "Failed to get method IDs"); |
| | | return env->NewStringUTF(""); |
| | | } |
| | | |
| | | // 获取应用签名信息 |
| | | jobject packageManagerObject = (env)->CallObjectMethod(contextObject, getPackageManagerId); |
| | | jstring packNameString = (jstring) (env)->CallObjectMethod(contextObject, getPackageNameId); |
| | | jobject packageInfoObject = (env)->CallObjectMethod(packageManagerObject, getPackageInfoId, |
| | | packNameString, 64); |
| | | jfieldID signaturefieldID = (env)->GetFieldID(packageInfoClass, "signatures", |
| | | "[Landroid/content/pm/Signature;"); |
| | | jobjectArray signatureArray = (jobjectArray) (env)->GetObjectField(packageInfoObject, |
| | | signaturefieldID); |
| | | jobject signatureObject = (env)->GetObjectArrayElement(signatureArray, 0); |
| | | jobject packageManagerObject = env->CallObjectMethod(contextObject, getPackageManagerId); |
| | | if (!packageManagerObject) { |
| | | __android_log_print(ANDROID_LOG_ERROR, "M1Card", "Failed to get PackageManager"); |
| | | return env->NewStringUTF(""); |
| | | } |
| | | |
| | | jstring packNameString = (jstring) env->CallObjectMethod(contextObject, getPackageNameId); |
| | | if (!packNameString) { |
| | | __android_log_print(ANDROID_LOG_ERROR, "M1Card", "Failed to get package name"); |
| | | return env->NewStringUTF(""); |
| | | } |
| | | |
| | | jobject packageInfoObject = env->CallObjectMethod(packageManagerObject, getPackageInfoId, |
| | | packNameString, 64); |
| | | if (!packageInfoObject) { |
| | | __android_log_print(ANDROID_LOG_ERROR, "M1Card", "Failed to get PackageInfo"); |
| | | return env->NewStringUTF(""); |
| | | } |
| | | |
| | | // 获取签名数组字段ID |
| | | jfieldID signaturefieldID = env->GetFieldID(packageInfoClass, "signatures", |
| | | "[Landroid/content/pm/Signature;"); |
| | | if (!signaturefieldID) { |
| | | __android_log_print(ANDROID_LOG_ERROR, "M1Card", "Failed to get signature field ID"); |
| | | return env->NewStringUTF(""); |
| | | } |
| | | |
| | | // 获取签名数组 |
| | | jobjectArray signatureArray = (jobjectArray) env->GetObjectField(packageInfoObject, |
| | | signaturefieldID); |
| | | if (!signatureArray || env->GetArrayLength(signatureArray) == 0) { |
| | | __android_log_print(ANDROID_LOG_ERROR, "M1Card", "No signatures found"); |
| | | return env->NewStringUTF(""); |
| | | } |
| | | |
| | | // 获取第一个签名对象 |
| | | jobject signatureObject = env->GetObjectArrayElement(signatureArray, 0); |
| | | if (!signatureObject) { |
| | | __android_log_print(ANDROID_LOG_ERROR, "M1Card", "Failed to get signature object"); |
| | | return env->NewStringUTF(""); |
| | | } |
| | | |
| | | // 获取签名字符串 |
| | | const char *signStrng = (env)->GetStringUTFChars( |
| | | (jstring) (env)->CallObjectMethod(signatureObject, signToStringId), 0); |
| | | jstring signatureString = (jstring) env->CallObjectMethod(signatureObject, signToStringId); |
| | | if (!signatureString) { |
| | | __android_log_print(ANDROID_LOG_ERROR, "M1Card", "Failed to get signature string"); |
| | | return env->NewStringUTF(""); |
| | | } |
| | | |
| | | // 调试日志输出 |
| | | __android_log_print(ANDROID_LOG_DEBUG, "M1Card", "Current signature: %s", signStrng); |
| | | // 获取签名字符串的UTF-8字符 |
| | | const char *signStrng = env->GetStringUTFChars(signatureString, 0); |
| | | if (!signStrng) { |
| | | __android_log_print(ANDROID_LOG_ERROR, "M1Card", "Failed to get signature UTF chars"); |
| | | return env->NewStringUTF(""); |
| | | } |
| | | |
| | | // 输出当前签名用于调试 |
| | | // __android_log_print(ANDROID_LOG_DEBUG, "M1Card", "Current signature: %s", signStrng); |
| | | |
| | | // 验证签名并返回所有扇区密码 |
| | | if (strcmp(signStrng, RELEASE_SIGN) == 0) { |
| | | size_t numKeys = sizeof(ENCRYPTED_SECTOR_KEYS) / 12; // 每个密钥12字节 |
| | | char *allKeys = new char[numKeys * 13]; // 为每个密钥预留12个字符+1个分隔符 |
| | | allKeys[0] = '\0'; |
| | | // 计算密钥数量 |
| | | size_t numKeys = sizeof(ENCRYPTED_SECTOR_KEYS) / 12; |
| | | std::string result; |
| | | result.reserve(numKeys * 13); // 每个密钥12个字符+1个分隔符 |
| | | |
| | | // 解密并转换每个扇区密钥 |
| | | for (size_t i = 0; i < numKeys; i++) { |
| | | char decrypted[13]; |
| | | decrypt_key(ENCRYPTED_SECTOR_KEYS + (i * 12), decrypted, 12); |
| | | |
| | | strcat(allKeys, decrypted); |
| | | if (i < numKeys - 1) { |
| | | strcat(allKeys, ","); |
| | | // __android_log_print(ANDROID_LOG_DEBUG, "M1Card", "处理扇区 %zu 的密钥", i); |
| | | |
| | | // 确保不会越界访问 |
| | | if (i * 12 + 6 > sizeof(ENCRYPTED_SECTOR_KEYS)) { |
| | | __android_log_print(ANDROID_LOG_ERROR, "M1Card", "Index out of bounds"); |
| | | break; |
| | | } |
| | | |
| | | // 获取解密后的字符串 |
| | | jstring decrypted_str = decrypt_key(env, ENCRYPTED_SECTOR_KEYS + (i * 12), 6); |
| | | |
| | | if (!decrypted_str) { |
| | | // __android_log_print(ANDROID_LOG_ERROR, "M1Card", "Failed to decrypt key for sector %zu", i); |
| | | continue; |
| | | } |
| | | |
| | | // 转换成C字符串 |
| | | const char* decrypted_chars = env->GetStringUTFChars(decrypted_str, 0); |
| | | |
| | | if (i > 0) { |
| | | result += ","; // 添加分隔符 |
| | | } |
| | | result += decrypted_chars; // 使用解密后的数据 |
| | | |
| | | // 释放资源 |
| | | env->ReleaseStringUTFChars(decrypted_str, decrypted_chars); |
| | | env->DeleteLocalRef(decrypted_str); |
| | | } |
| | | |
| | | jstring result = (env)->NewStringUTF(allKeys); |
| | | delete[] allKeys; |
| | | return result; |
| | | // 释放资源并返回结果 |
| | | env->ReleaseStringUTFChars(signatureString, signStrng); |
| | | return env->NewStringUTF(result.c_str()); |
| | | } else { |
| | | return (env)->NewStringUTF("signature_verification_failed"); |
| | | // 签名验证失败 |
| | | __android_log_print(ANDROID_LOG_ERROR, "M1Card", "Signature verification failed"); |
| | | env->ReleaseStringUTFChars(signatureString, signStrng); |
| | | return env->NewStringUTF(""); |
| | | } |
| | | } |
| | | |