1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
| #include <jni.h>
| #include <string>
| #include <android/log.h>
| #include <string.h>
| #include <jni.h>
| #include <sstream>
| #include <iomanip>
|
| // 声明全局静态变量,用于存储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}; // 修改后三个字节的密钥
|
| // 定义后半部分XOR密钥数组
| const unsigned char XOR_KEY_BACK[] = {0x4D, 0xE4, 0x7C, 0x2A, 0x8B, 0x7F};
|
| // 定义加密后的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
| };
|
| // 将字节数组转换为十六进制字符串的函数
| 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++) {
| ss << std::setw(2) << static_cast<int>(data[i]); // 将每个字节转换为两位十六进制
| }
| return ss.str(); // 返回转换后的字符串
| }
|
| // 解密函数:使用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; // 声明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(
| (env)->FindClass("android/content/pm/PackageManager"));
| packageInfoClass = (jclass) env->NewGlobalRef(
| (env)->FindClass("android/content/pm/PackageInfo"));
|
| __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;");
|
| // 检查方法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);
| 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("");
| }
|
| // 获取签名字符串
| jstring signatureString = (jstring) env->CallObjectMethod(signatureObject, signToStringId);
| if (!signatureString) {
| __android_log_print(ANDROID_LOG_ERROR, "M1Card", "Failed to get signature string");
| return env->NewStringUTF("");
| }
|
| // 获取签名字符串的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;
| std::string result;
| result.reserve(numKeys * 13); // 每个密钥12个字符+1个分隔符
|
| // 解密并转换每个扇区密钥
| for (size_t i = 0; i < numKeys; i++) {
| // __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);
| }
|
| // 释放资源并返回结果
| env->ReleaseStringUTFChars(signatureString, signStrng);
| return env->NewStringUTF(result.c_str());
| } else {
| // 签名验证失败
| __android_log_print(ANDROID_LOG_ERROR, "M1Card", "Signature verification failed");
| env->ReleaseStringUTFChars(signatureString, signStrng);
| return env->NewStringUTF("");
| }
| }
|
|