• c++实现加密和解密算法以及JNI技术的应用实例


    #include "jiami.h"
    
    #include "jni.h"
    #include "com_test_start_CommonClassLoader.h"
    
     static void arraycopy(JNIEnv * env, jbyteArray sb, int spo, jbyteArray db,
                      int start, int len);
    
    static jbyteArray encrypt(JNIEnv * env, jbyteArray b, jint len);
    static jbyteArray getValidateCode(JNIEnv * env);
    static jbyteArray getCode(JNIEnv * env);
    
    /* * Clasbs:  com_test_start_CommonClassLoader
    * Method:    defineClass0
    * Signature: (Ljava/lang/String;[BII)Ljava/lang/Class;
    */
    JNIEXPORT jclass JNICALL Java_com_test_start_CommonClassLoader_defineClass0(
            JNIEnv * env, jobject loader, jstring name, jbyteArray buffer,
            jint start, jint len) {
        jbyteArray temp = env - > NewByteArray(len); //new一个数组,并申请一块内存
        arraycopy(env, buffer, start, temp, start, len); //数组的复制相当于System.copy()方法
        jbyteArray byte0 = encrypt(env, temp, len); //进行class文件的解密操作
        if (byte0 == NULL) {
            env - > DeleteLocalRef(temp); //释放内存
            return NULL;
        }
        jsize size = env - > GetArrayLength(byte0); //技术数组的长度相当于Array的length属性
        jclass classLoader = env - >
                             GetSuperclass(env - >
                                           GetSuperclass(env - >
                GetSuperclass(env - > GetObjectClass(loader)))); //获取父类装载器
        jmethodID mid = env - >
                        GetMethodID(classLoader, "defineClass",
                                    "(Ljava/lang/String;[BII)Ljava/lang/Class;"); //获取defineClass方法
        defineClass jclass cls = (jclass) env - >
                                 CallObjectMethod(loader, mid, name, byte0, start,
                                                  size); //调用Classloader的defineClass定义一个类到jvm中
        env - > DeleteLocalRef(byte0); //释放内存
        return cls;
    }
    /* 
    * Class:     com_test_start_CommonClassLoader 
    * Method:    defineClass1 
    * Signature: (Ljava/lang/String;[BIILjava/security/ProtectionDomain;)Ljava/lang/Class; 
    */
    JNIEXPORT jclass JNICALL Java_com_test_start_CommonClassLoader_defineClass1(
            JNIEnv * env, jobject loader, jstring name, jbyteArray buffer,
            jint start, jint len, jobject pro) {
        jbyteArray temp = env - > NewByteArray(len);
        arraycopy(env, buffer, start, temp, start, len);
        jbyteArray byte0 = encrypt(env, temp, len);
        if (byte0 == NULL) {
            env - > DeleteLocalRef(temp);
            return NULL;
        }
        jsize size = env - > GetArrayLength(byte0);
        jclass classLoader = env - >
                             GetSuperclass(env - >
                                           GetSuperclass(env - >
                GetSuperclass(env - > GetObjectClass(loader))));
        jmethodID mid = env - >
                        GetMethodID(classLoader, "defineClass",
                                    "(Ljava/lang/String;[BIILjava/security/ProtectionDomain;)Ljava/lang/Class;");
        jclass cls = (jclass) env - >
                     CallObjectMethod(loader, mid, name, byte0, start, size, pro);
        env - > DeleteLocalRef(byte0);
        return cls;
    }
    /*   getCode,密钥,用于加密  */
    static jbyteArray getCode(JNIEnv * env) {
        char char0[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
        char char1[] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
                       'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 's',
                       'y', 'z'
        };
        char char2[36];
        int i = 0;
        int j = 0;
        int k = 0;
        while (i < 36) {
            if (i >= 12 && j < 10) {
                char2[i] = char0[j];
                j++;
            } else if (i >= 23 && k < 26) {
                char2[i] = char1[k];
                k++;
            } else {
                char2[i] = char1[k];
                k++;
            }
            i++;
        }
        jbyteArray code = env - > NewByteArray(36);
        env - > SetByteArrayRegion(code, 0, 36, (jbyte * ) char2);
        return code;
    }
    /*   getValidateCode,验证码用于区分是否是加密文件  */
    static jbyteArray getValidateCode(JNIEnv * env) {
        char char0[] = {'0', '1', '2', '3', '4', '5', '6', '7'};
        jbyteArray char1 = env - > NewByteArray(8);
        env - > SetByteArrayRegion(char1, 0, 8, (jbyte * ) char0);
        return char1;
    }
    /*   encrypt,解密操作   */
    static jbyteArray encrypt(JNIEnv * env, jbyteArray b, jint len) {
        int i = 0;
        jint j = 0;
        int k = len;
        jbyte * bb = (env - > GetByteArrayElements(b, JNI_FALSE));
        while (i < k) {
            j = bb[i];
            if ((j >= 48) && (j <= 57)) {
                j = (((j - 48) + 5) % 10) + 48;
            } else if ((j >= 65) && (j <= 90)) {
                j = (((j - 65) + 13) % 26) + 65;
            } else if ((j
                        >= 97) && (j <= 122)) {
                j = (((j - 97) + 13) % 26) + 97;
            }
            bb[i] = (jbyte) j;
            i++;
        }
        env - > SetByteArrayRegion(b, 0, k, bb);
        int length = 500; //长度
        int start = 0; //起始次数
        jbyteArray temp = getCode(env); //密钥
        int mode = (k - 8) % (length + 36); //剩余部分
        int count = (k - 8) / (length + 36); //总次数
        int spo = 0; //源位置
        int dpo = 0; //目标位置
        int size = count * length + mode; //大小
        jbyteArray byte0 = env - > NewByteArray(size); //密文大小
        if (count > 0) { //进行解密
            while (start < count) {
                arraycopy(env, b, spo, byte0, dpo, length);
                spo = spo + length + 36;
                dpo = dpo + length;
                start++;
            }
        }
        if (mode > 0) { //复制剩余部分
            arraycopy(env, b, spo, byte0, dpo, mode);
            spo = spo + mode;
        } //校验码
        jbyteArray validateCode0 = getValidateCode(env);
        jbyte *
                validateCode = env - >
                               GetByteArrayElements(validateCode0, JNI_FALSE);
        jbyteArray validate0 = env - > NewByteArray(8);
        arraycopy(env, b, spo, validate0, 0, 8);
        jbyte * validate = env - > GetByteArrayElements(validate0, JNI_FALSE);
        for (int index = 0; index < 8; index++) { //校验解码是否成功
            if (validate[index] != validateCode[index]) {
                return NULL;
            }
        }
        env - > DeleteLocalRef(validate0);
        env - > DeleteLocalRef(validateCode0);
        env - > DeleteLocalRef(temp);
        return byte0;
    }
    /*    decrypt,加密操作    */
    static jbyteArray decrypt(JNIEnv * env, jbyteArray b, jboolean end) {
        int length = 500; //长度
        int start = 0; //起始次数
        int count = env - > GetArrayLength(b) / length; //总次数
        jbyteArray temp = getCode(env); //密钥
        int spo = 0; //源位置
        int dpo = 0; //目标位置
        int mode = env - > GetArrayLength(b) % length; //剩余部分
        int size = count * (length + 36) + mode; //大小
        if (end == JNI_TRUE) { //是否结束
            size = size + 8;
        }
        jbyteArray byte0 = env - > NewByteArray(size); //密文大小
        if (count > 0) { //进行加密
            while (start < count) {
                arraycopy(env, b, spo, byte0, dpo, length);
                arraycopy(env, temp, 0, byte0, dpo + length, 36);
                spo = spo + length;
                dpo = dpo + length + 36;
                start++;
            }
        }
        if (mode > 0) { //复制剩余部分
            arraycopy(env, b, spo, byte0, dpo, mode);
            dpo = dpo + mode;
        }
        if (end == JNI_TRUE) { //结束位置加校验码
            jbyteArray validateCode = getValidateCode(env);
            arraycopy(env, validateCode, 0, byte0, dpo, 8);
            env - > DeleteLocalRef(validateCode);
        }
        jbyte * byte1 = env - > GetByteArrayElements(byte0, 0); //转换字节位置
        int i = 0;
        int j = 0;
        int k = size;
        while (i < k) {
            j = byte1[i];
            if ((j >= 48) && (j <= 57)) {
                j = (((j - 48) + 5) % 10) + 48;
            } else if ((j >= 65) && (j <= 90)) {
                j = (((j - 65) + 13) % 26) + 65;
            } else if ((j >= 97) && (j <= 122)) {
                j = (((j - 97) + 13) % 26) + 97;
            }
            byte1[i] = (jbyte) j;
            i++;
        }
        env - > SetByteArrayRegion(byte0, 0, size, byte1);
        env - > DeleteLocalRef(temp);
        return byte0;
    }
    /*   arraycopy,自定义的数组赋值方法相当于System.copy()   */
    static void arraycopy(JNIEnv * env, jbyteArray sb, int spo, jbyteArray db,
                          int start, int len) {
        jbyte * t = new jbyte[len];
        env - > GetByteArrayRegion(sb, spo, len, t);
        env - > SetByteArrayRegion(db, start, len, t);
        delete t;
    }
    

      参考:http://blog.csdn.net/chenshuang_com/article/details/7681670

    使用定制ClassLoader来对保护j2ee程序

    http://www.ibm.com/developerworks/cn/java/l-protectjava/

  • 相关阅读:
    如何在.netcore 上实现 Rbac 权限管理
    socket编程之TCP开发中的PEEK_MSG的使用与见解
    简述单例模式的一些优缺点及其评价
    排查线上内存泄漏,RingBufferLogEvent类内存占用过高,skyWalking内存占用过高
    Centos7安装docker(报错:container-selinux >= 2:2.74)
    JSP3.4
    Java SM2加密、解密、签名、验签
    获取properties文件中的
    五种生成唯一id方式的对比
    SpringBoot 改造成 https访问
  • 原文地址:https://www.cnblogs.com/langtianya/p/3752883.html
Copyright © 2020-2023  润新知