Shell's Home

Nov 10, 2005 - 2 minute read - Comments

JNI试用记

    近两天要用JIN做数据加密系统,所以特别写了这篇。省得以后忘记,顺便造福大家。
    下面是核心编码:
//CTX.java
public abstract class CTX {\  protected byte\[\] state = new byte\[20\];
 protected long count;
 protected byte\[\] buffer = new byte\[0\]; /\* input buffer \*/
 protected byte\[\] PADDING = { -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\    0, 0, 0, 0, 0, 0 };
 // 大端点序\  protected static void putChar(byte\[\] b, int off, char val) ;
 // 大端点序\  protected static void putLong(byte\[\] b, int off, long val) ;
 static {\   System.loadLibrary("cryptogram\_jni");\  }
 public CTX();
 public void Update(String str);
 public void Update(char\[\] input) ;
 public void Update(byte\[\] input);
 public void Update(byte\[\] input, int length) ;
 public byte\[\] Final() ;
 public String GetHash() ;
 protected abstract void init();
 protected abstract void Transform();\ }
//MD5\_CTX.java
public class MD5\_CTX extends CTX {\  protected native void init();\  protected native void Transform();\ }
    然后导出h文件,在工程目录下执行这个。记得要先编译过代码,否则会说找不到。
javah -jni com.XXX.MD5\_CTX
    如果要看Signature的话执行这个。同样需要先编译代码。
javap -s -p com.XXX.MD5\_CTX
    把.h复制到c的工程目录,然后变换一下。
extern "C"\ JNIEXPORT\ void\ JNICALL\ Java\_com\_anhorn\_cryptogram\_MD5\_1CTX\_init(\  JNIEnv \*env,\  jobject obj\ ){\  JavaCTX jctx(env, obj);\  jctx.jl\_count=0;
 jctx.pd\_state\[0\] = 0x67452301L;\  jctx.pd\_state\[1\] = 0xefcdab89L;\  jctx.pd\_state\[2\] = 0x98badcfeL;\  jctx.pd\_state\[3\] = 0x10325476L;
 return ;\ }
    如果按照原来的数据,马上会出现导出函数变成乱码的乌龙场景。其中JavaCTX的定义是这样的。
class JavaClass{\ public:\  JavaClass(JNIEnv \*env, jobject obj){\   this->env=env;\   this->obj=obj;\   this->cls=env->GetObjectClass(obj);\  }\ protected:\  JNIEnv \*env;\  jobject obj;\  jclass cls;\ };
class JavaCTX : public JavaClass{\ public:\  JavaCTX(JNIEnv \*env, jobject obj);\  \~JavaCTX();\ protected:\  jbyteArray jba\_state;\  jbyteArray jba\_buffer;\  jfieldID jfid\_count;\ public:\  jsize js\_state\_size;\  PDWORD pd\_state;\  jlong jl\_count;\  jsize js\_buffer\_size;\  PBYTE pb\_buffer;\ };
JavaCTX::JavaCTX(JNIEnv \*env, jobject obj):JavaClass(env, obj){\  jfieldID jfid\_state, jfid\_buffer;
 cls=env->GetSuperclass(cls);\  jfid\_state=env->GetFieldID(cls, "state", "\[B");\  jba\_state=(jbyteArray)env->GetObjectField(obj, jfid\_state);\  js\_state\_size=env->GetArrayLength(jba\_state);\  pd\_state=(PDWORD)env->GetByteArrayElements(jba\_state, JNI\_FALSE);
 jfid\_count=env->GetFieldID(cls, "count", "J");\  jl\_count=env->GetLongField(obj, jfid\_count);
 jfid\_buffer=env->GetFieldID(cls, "buffer", "\[B");\  jba\_buffer=(jbyteArray)env->GetObjectField(obj, jfid\_buffer);\  js\_buffer\_size=env->GetArrayLength(jba\_buffer);\  pb\_buffer=(PBYTE)env->GetByteArrayElements(jba\_buffer, JNI\_FALSE);
 return ;\ }
JavaCTX::\~JavaCTX(){\  env->ReleaseByteArrayElements(jba\_buffer,\   (jbyte\*)pb\_buffer, JNI\_COMMIT);\  env->SetLongField(obj, jfid\_count, jl\_count);\  env->ReleaseByteArrayElements(jba\_state,\   (jbyte\*)pd\_state, JNI\_COMMIT);\ }
    这样就将Java中的一个特定对象在C++里面读了出来,然后下面大家都知道了。关键的native void Transform();在C++中的实现是Java\_com\_anhorn\_cryptogram\_MD5\_1CTX\_Transform。这个调用了MD5\_CTX\_Transform, which是我做的一个MD5算法。

Tags: c java program

被骗了 SrouceForge

comments powered by Disqus