左晓为主开发手持机充值管理机
zuoxiao
2025-03-07 0ec9693c39a910233fc186a8cefab9f61030df78
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
#include <jni.h>
#include <string>
#include <android/log.h>
#include <string.h>
#include <jni.h>
 
static jclass contextClass;
static jclass signatureClass;
static jclass packageNameClass;
static jclass packageInfoClass;
 
const char *RELEASE_SIGN = "308202b8308201a0020101300d06092a864886f70d01010b05003022310f300d06035504030c06e5a4a7e7a6b9310f300d06035504070c06e5a4a9e6b4a5301e170d3233313132303035333131325a170d3438313131333035333131325a3022310f300d06035504030c06e5a4a7e7a6b9310f300d06035504070c06e5a4a9e6b4a530820122300d06092a864886f70d01010105000382010f003082010a0282010100a0924f3d618e4a622def691e16e54ce5bdfd035bd73e7cb947d2bf3bd0c00afa26e52963e0299fc06d76d153be696c5285d630577e1dcb2b740a72b6d904482217de308fb91c8435441ed05e844ced1e5c3446d82cb8f38751049df26a42adcfc33f1f12c2ce03f676e5d148aad800ace89670b87835e2c02a8570a0b6740d9c0669d4cb3c597d0b2dd49fc0904e885773b6d3a87d9f1e73eb526e0d1a9e9e3c48d986938286cd824151b5a6214faf89d3e699524511b23c86d3b110a7f0bb56a6d2436f69816538a62a38cb1fee6eb685d267cc200df8af51b936bd280beaa2023f75678d77a11ac6de734b30af63d394c8b63bccf2115a47ea15c9212c740d0203010001300d06092a864886f70d01010b05000382010100307cafa9b14be91ba6424cfcc6aed75b069a1c4d6eb646eab0de93f372f236f5f0a6097499df99391075d6ced18d419a2b15adb041890e2b56a3bfbd6be40efee99c5c713ba8ea1d45da09b67916106116e96eb735271c4d53e0739f753145cbc42e149ad3d9507d422ec1c6f1a7f792a4542f9a64f0de3d4f4af69f0fb3390ef3577dcf8844cf744426d173b0934d879148062c5ca64022dc99af370dbfeaf2b5d4a279b20c54a361bca12c25bf185c2885519bbbc36e46ddb083080f0cc5b1f2eafe964ebce5071b0ae7d92a34a9193861b996d2c0299b1993f41063a27038199365a6e3cb27a02ffa9facdc48a63713eb5fbf90e9fd73056aba16b28e5fee";
 
 
// 加密密钥
const unsigned char XOR_KEY[] = {0x7A, 0xB3, 0xC9, 0xD5, 0xE1, 0xF8, 0x42, 0x91, 0x37, 0x8F, 0x5D,
                                 0x2E};
 
// 加密后的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
};
 
// 解密函数
void decrypt_key(const unsigned char *encrypted, char *decrypted, size_t len) {
    for (size_t i = 0; i < len; i++) {
        decrypted[i] = encrypted[i] ^ XOR_KEY[i % sizeof(XOR_KEY)];
    }
    decrypted[len] = '\0';
}
 
//extern "C" JNIEXPORT jstring
//
//JNICALL
//Java_com_yglx_testjni_MainActivity_getKey(
//        JNIEnv *env,
//        jobject /* this */) {
//    return env->NewStringUTF(AUTH_KEY);
//}
 
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
 
    JNIEnv *env = NULL;
    jint result = -1;
    if (vm->GetEnv((void **) &env, JNI_VERSION_1_4) != JNI_OK)
        return result;
 
    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, "jw", "sss");
    return JNI_VERSION_1_4;
}
 
 
extern "C"
JNIEXPORT jstring JNICALL
Java_com_dayu_general_tool_GeBaseHelper_getM1SectorKeySecure(JNIEnv *env, jobject instance,
                                                             jobject contextObject,
                                                             jint sectorIndex) {
    // 获取包管理器相关方法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;");
 
    // 获取应用签名信息
    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);
 
    // 获取签名字符串
    const char *signStrng = (env)->GetStringUTFChars(
            (jstring) (env)->CallObjectMethod(signatureObject, signToStringId), 0);
 
    // 调试日志输出
    __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';
 
        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, ",");
            }
        }
 
        jstring result = (env)->NewStringUTF(allKeys);
        delete[] allKeys;
        return result;
    } else {
        return (env)->NewStringUTF("signature_verification_failed");
    }
}