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/

你可能感兴趣的:(C++)