TEA加密解法,统一了C语言、Java与PHP的运算结果 TEA 加密解法,统一了C语言、Java与PHP的运算结果
去年PHP与Andriod终端通讯,想使用TEA加密,却发现Java实现的TEA只能由Java解密、PHP实现的TEA只能由PHP解密。这不是我们想要的。 昨天中午有空,想起加密这回事,仔细研究了TEA算法,本人笨,经过十五个小时的摸索,终于实现了C语言、Java与32bit的PHP加密解密一致性。
首先,来一段网上流行的C语言描述的TEA算法:
#include <stdint.h>
void encrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i < 32; i++) { /* basic cycle start */
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) {
uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i<32; i++) { /* basic cycle start */
v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
sum -= delta;
} /* end cycle */
v[0]=v0; v[1]=v1;
}
这段代码出现在Wiki百科、百度百科,描述的就是TEA加密解密算法的核心。可惜,如果不加思考与分析,就使用这段代码,就完蛋了。因为这是一段错误的代码。 TEA加密,就是使用一个128bit的密钥,对64bit的明文,经过16轮、32轮或64轮的运算,
生成64bit的密文。下面是我修改过的代码:
#include <stdio.h>
#include <stdint.h>
void encrypt (uint32_t v[], uint32_t k[]) {
uint32_t v0=v[0], v1=v[1], sum=0, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i < 32; i++) { /* basic cycle start */
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[]) {
uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i<32; i++) { /* basic cycle start */
v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
sum -= delta;
} /* end cycle */
v[0]=v0; v[1]=v1;
}
int main() {
uint32_t v[2] = {0x20, 0x10}, k[4] = {0x04, 0x03, 0x02, 0x01};
printf("Encrypt And Decrypt:\n");
printf("%08X%08X\n", v[0], v[1]);
encrypt(v, k);
printf("%08X%08X\n", v[0], v[1]);
decrypt(v, k);
printf("%08X%08X\n", v[0], v[1]);
printf("Key:\n");
printf("%08X%08X%08X%08X\n", k[0], k[1], k[2], k[3]);
return 0;
}
相对于C语言,Java显示非常臃肿,可能是本人Java水平太次了,只能写成这样子了。下面是Java的实现:
/**
* @author: heiing 2013-01-20 01:20
*/
public class TEA {
public static byte[] encrypt(byte[] data, byte[] key) {
int data_len = data.length; // 数据的长度
if (data_len == 0) {
return new byte[] {};
}
TEA t = new TEA();
if (!t.setKey(key)) {
return new byte[] {};
}
int group_len = 8;
int residues = data_len % group_len; // 余数
int dlen = data_len - residues;
// 用于储存加密的密文,第一字节为余数的大小
int result_len = data_len + 1;
if (residues > 0) {
result_len += group_len - residues;