通过JNI调用LibTEA 加密算法
2015-11-11 17:23
232 查看
最近在做的项目的传输系统上使用了TEA加密,采集端使用Java,但是说实在的换了多少个版本的Java实现都不能正确解密。。。
先简单介绍下TEA,据说QQ也在用。
TEA(Tiny Encryption Algorithm) 是一种简单高效的加密算法,以加密解密速度快,实现简单著称。算法真的很简单,TEA算法每一次可以操作64-bit(8-byte),采用128-bit(16-byte)作为key,算法采用迭代的形式,推荐的迭代轮数是64轮,最少32轮。目前我只知道QQ一直用的是16轮TEA。没什么好说的,先给出C语言的源代码(默认是32轮)。
C语言实现:
tea_encrypt.h
tea_encrypt.c
0、写个Java的native类
1、生成C语言的头文件
2、实现TeaJniNative.h方法,调用tea_encrypt.h的加密解密方法
3、gcc编译生成.so,将该文件目录加入LD_LIBRARY_PATH中
Ex:
Output:
先简单介绍下TEA,据说QQ也在用。
TEA(Tiny Encryption Algorithm) 是一种简单高效的加密算法,以加密解密速度快,实现简单著称。算法真的很简单,TEA算法每一次可以操作64-bit(8-byte),采用128-bit(16-byte)作为key,算法采用迭代的形式,推荐的迭代轮数是64轮,最少32轮。目前我只知道QQ一直用的是16轮TEA。没什么好说的,先给出C语言的源代码(默认是32轮)。
C语言实现:
tea_encrypt.h
#include <stdint.h> /*void encrypt(uint32_t v[], uint32_t k[]); void decrypt(uint32_t v[], uint32_t k[]);*/ extern void encrypt(uint32_t v[]); extern void decrypt(uint32_t v[]);
tea_encrypt.c
#include "tea_encrypt.h" static uint32_t tea_keys[4] = {0x2B6D5E6D, 0x24AAB7C3, 0x0E3E55F0, 0x21241BA9}; /*void encrypt(uint32_t v[], uint32_t k[])*/ void encrypt(uint32_t v[]) { uint32_t v0 = v[0], v1 = v[1], sum = 0, i = 0; /* set up */ uint32_t delta = 0x9E378198; /* a key schedule constent */ uint32_t k0 = tea_keys[0], k1 = tea_keys[1], k2 = tea_keys[2], k3 = tea_keys[3]; /* cache key*/ for(i=0; i<32; i++) { sum += delta; v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1); v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3); /* end cycle */ } v[0] = v0; v[1] = v1; } /*void decrypt(uint32_t v[], uint32_t k[])*/ void decrypt(uint32_t v[]) { uint32_t v0 = v[0], v1 = v[1], sum = 0xC6F03300, i = 0; /* set up */ uint32_t delta = 0x9E378198; /* a key schedule */ uint32_t k0 = tea_keys[0], k1 = tea_keys[1], k2 = tea_keys[2], k3 = tea_keys[3]; /* cache key*/ sum = delta << 5; for(i=0; i<32; i++) { v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3); v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1); sum -= delta; } v[0] = v0; v[1] = v1; }
0、写个Java的native类
public class TeaJniNative { static { System.loadLibrary("libtea_native"); } public native byte[] encrypt(byte[] v); public native byte[] decrypt(byte[] v); }
1、生成C语言的头文件
javac TeaJniNative.java javah TeaJniNative
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class TeaJniNative */ #ifndef _Included_TeaJniNative #define _Included_TeaJniNative #ifdef __cplusplus extern "C" { #endif /* * Class: TeaJniNative * Method: encrypt * Signature: ([B)[B */ JNIEXPORT jbyteArray JNICALL Java_TeaJniNative_encrypt (JNIEnv *, jobject, jbyteArray); /* * Class: com_liuxiaobai_TeaJniNative * Method: decrypt * Signature: ([B)[B */ JNIEXPORT jbyteArray JNICALL Java_TeaJniNative_decrypt (JNIEnv *, jobject, jbyteArray); #ifdef __cplusplus } #endif #endif
2、实现TeaJniNative.h方法,调用tea_encrypt.h的加密解密方法
/* Replace "dll.h" with the name of your header */ #include "TeaJniNative.h" #include "tea_encrypt.h" JNIEXPORT jbyteArray JNICALL Java_TeaJniNative_encrypt (JNIEnv *env, jobject obj, jbyteArray input) { jbyte *pJbyte = (*env)->GetByteArrayElements(env, input, JNI_FALSE); jsize len = (*env)->GetArrayLength(env, input); uint8_t *v = (uint8_t *)pJbyte; uint32_t offset; for(offset = 0;(offset + 8) <= len;offset += 8) { encrypt((uint32_t *)(v + offset)); } jbyteArray output = (*env)->NewByteArray(env, len); (*env)->SetByteArrayRegion(env, output, 0, len, pJbyte); return output; } JNIEXPORT jbyteArray JNICALL Java_TeaJniNative_decrypt (JNIEnv *env, jobject obj, jbyteArray input) { jbyte *pJbyte = (*env)->GetByteArrayElements(env, input, JNI_FALSE); jsize len = (*env)->GetArrayLength(env, input); uint8_t *v = (uint8_t *)pJbyte; uint32_t offset; for(offset = 0;(offset + 8) <= len;offset += 8) { decrypt((uint32_t *)(v + offset)); } jbyteArray output = (*env)->NewByteArray(env, len); (*env)->SetByteArrayRegion(env, output, 0, len, pJbyte); return output; }
3、gcc编译生成.so,将该文件目录加入LD_LIBRARY_PATH中
gcc -m64 -fPIC -c src/TeaJniNative.c -o src/TeaJniNative.o -I/opt/develop_tools/jdk1.7.0_79/include -I/opt/develop_tools/jdk1.7.0_79/include/linux -DBUILDING_DLL=1 gcc -m64 -fPIC -c src/tea_encrypt.c -o src/tea_encrypt.o -I/opt/develop_tools/jdk1.7.0_79/include -I/opt/develop_tools/jdk1.7.0_79/include/linux -DBUILDING_DLL=1 gcc -m64 -shared src/TeaJniNative.o src/tea_encrypt.o -o libtea_native.so
Ex:
public class Main { public static void main(String[] args) { TeaJniNative tea = new TeaJniNative(); byte[] res0 = new byte[]{ 0x00, 0x30, 0x30, 0x30, 0x43, 0x32, 0x39, 0x10 }; int i; for(i = 0; i < res0.length; i++){ System.out.printf("[%02X]", res0[i]); } System.out.println(); byte[] res1 = tea.encrypt(res0); for(i = 0; i < res1.length; i++){ System.out.printf("[%02X]", res1[i]); } System.out.println(); byte[] res2 = tea.decrypt(res1); for(i = 0; i < res2.length; i++){ System.out.printf("[%02X]", res2[i]); } System.out.println(); } }
Output:
[00][30][30][30][43][32][39][10] [1B][01][2F][7F][DF][7B][3D][C2] [00][30][30][30][43][32][39][10]
相关文章推荐
- 浏览同学文法推导的感想
- 评论十人份
- yycg 之供货商药品目录模块分析
- 运行软件时遇到windows已保护你的电脑怎么办?
- CSS属性之Overflow
- Qt Quick 图像处理实例之美图秀秀(附源码下载)
- tabBarItem设置背景色,标题
- 语法树和文法的评价
- Android Mvc 实现
- 015 - 3Sum
- 根据传智播客ibatis视频教程编写的入门例子
- 解析UML类图符号的含义
- 给了一串数字:218916754,根据下面规则可以找出扣扣号码:首先删除第一个数,紧接着将第二个数放到这串数字的末尾,再将第三个数删除,并将第四个数放到这串数字的末尾......如此循环,知道剩下最后
- Android之判断是否有网封装类
- htmlunit官网简易教程(翻译)
- 背包九讲(各种背包问题)
- iOS9项目打包上线(个人记录,2015年11月11日)
- 读Android Picasso源码有感
- Android使用UncaughtExceptionHandler捕获全局异常
- 014 - Longest Common Prefix