java tea加密_TEA 加密解法,统一了C语言、Java与PHP的运算结果

本文详细介绍了TEA(Tiny Encryption Algorithm)加密算法的Java实现,包括加密和解密过程,以及密钥设置和加密轮数的设定。代码中展示了如何对数据进行分组加密和填充处理,同时提供了加密和解密的内部逻辑。
摘要由CSDN通过智能技术生成

/**

* @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;

}

byte[] result = new byte[result_len];

result[0] = (byte)residues;

byte[] plain = new byte[group_len];

byte[] enc = new byte[group_len];

for (int i = 0; i < dlen; i += group_len) {

for (int j = 0; j < group_len; j++) {

plain[j] = data[i + j];

}

enc = t.encrypt_group(plain);

for (int k = 0; k < group_len; k++) {

result[i + k + 1] = enc[k];

}

}

if (residues > 0) {

for (int j = 0; j < residues; j++) {

plain[j] = data[dlen + j];

}

int padding = group_len - residues;

for (int j = 0; j < padding; j++) {

plain[residues + j] = (byte)0x00;

}

enc = t.encrypt_group(plain);

for (int k = 0; k < group_len; k++) {

result[dlen + k + 1] = enc[k];

}

}

return result;

}

public static byte[] decrypt(byte[] data, byte[] key) {

int group_len = 8;

if (data.length % group_len != 1) {

return new byte[] {};

}

TEA t = new TEA();

if (!t.setKey(key)) {

return new byte[] {};

}

int data_len = data.length - 1, dlen; //数据的长度

int residues = (int)(data[0]); //余数

if (residues > 0) {

dlen = data_len - group_len;

} else {

dlen = data_len;

}

byte[] result = new byte[dlen + residues];

byte[] dec = new byte[group_len];

byte[] enc = new byte[group_len];

for (int i = 0; i < dlen; i += group_len) {

for (int j = 0; j < group_len; j++) {

enc[j] = data[i + j + 1];

}

dec = t.decrypt_group(enc);

for (int k = 0; k < group_len; k++) {

result[i + k] = dec[k];

}

}

if (residues > 0) {

for (int j = 0; j < group_len; j++) {

enc[j] = data[dlen + j + 1];

}

dec = t.decrypt_group(enc);

for (int k = 0; k < residues; k++) {

result[dlen + k] = dec[k];

}

}

return result;

}

/*** 设置密钥

*@paramk 密钥

*@return密钥长度为16个byte时, 设置密钥并返回true,否则返回false*/

public boolean setKey(byte[] k) {

if (k.length != 16) {

return false;

}

k0 = bytes_to_uint32(new byte[] {k[0], k[1], k[2], k[3]});

k1 = bytes_to_uint32(new byte[] {k[4], k[5], k[6], k[7]});

k2 = bytes_to_uint32(new byte[] {k[8], k[9], k[10], k[11]});

k3 = bytes_to_uint32(new byte[] {k[12], k[13], k[14], k[15]});

return true;

}

/*** 设置加密的轮数,默认为32轮

*@paramloops 加密轮数

*@return轮数为16、32、64时,返回true,否则返回false*/

public boolean setLoops(int loops) {

switch (loops) {

case 16:

case 32:

case 64:

this.loops = loops;

return true;

}

return false;

}

private static long UINT32_MAX = 0xFFFFFFFFL;

private static long BYTE_1 = 0xFFL;

private static long BYTE_2 = 0xFF00L;

private static long BYTE_3 = 0xFF0000L;

private static long BYTE_4 = 0xFF000000L;

private static long delta = 0x9E3779B9L;

private long k0, k1, k2, k3;

private int loops = 32;

/*** 加密一组明文

*@paramv 需要加密的明文

*@return返回密文*/

private byte[] encrypt_group(byte[] v) {

long v0 = bytes_to_uint32(new byte[] {v[0], v[1], v[2], v[3]});

long v1 = bytes_to_uint32(new byte[] {v[4], v[5], v[6], v[7]});

long sum = 0L;

long v0_xor_1 = 0L, v0_xor_2 = 0L, v0_xor_3 = 0L;

long v1_xor_1 = 0L, v1_xor_2 = 0L, v1_xor_3 = 0L;

for (int i = 0; i < loops; i++) {

sum = toUInt32(sum + delta);

v0_xor_1 = toUInt32(toUInt32(v1 << 4) + k0);

v0_xor_2 = toUInt32(v1 + sum);

v0_xor_3 = toUInt32((v1 >> 5) + k1);

v0 = toUInt32( v0 + toUInt32(v0_xor_1 ^ v0_xor_2 ^ v0_xor_3) );

v1_xor_1 = toUInt32(toUInt32(v0 << 4) + k2);

v1_xor_2 = toUInt32(v0 + sum);

v1_xor_3 = toUInt32((v0 >> 5) + k3);

System.out.printf("%08X\t%08X\t%08X\t%08X\n", i, v0, v0 >> 5, k3);

v1 = toUInt32( v1 + toUInt32(v1_xor_1 ^ v1_xor_2 ^ v1_xor_3) );

}

byte[] b0 = long_to_bytes(v0, 4);

byte[] b1 = long_to_bytes(v1, 4);

return new byte[] {b0[0], b0[1], b0[2], b0[3], b1[0], b1[1], b1[2], b1[3]};

}

/*** 解密一组密文

*@paramv 要解密的密文

*@return返回明文*/

private byte[] decrypt_group(byte[] v) {

long v0 = bytes_to_uint32(new byte[] {v[0], v[1], v[2], v[3]});

long v1 = bytes_to_uint32(new byte[] {v[4], v[5], v[6], v[7]});

long sum = 0xC6EF3720L, tmp = 0L;

for (int i = 0; i < loops; i++) {

tmp = toUInt32(toUInt32(v0 << 4) + k2);

v1 = toUInt32( v1 - toUInt32(tmp ^ toUInt32(v0 + sum) ^ toUInt32((v0 >> 5) + k3)) );

tmp = toUInt32(toUInt32(v1 << 4) + k0);

v0 = toUInt32( v0 - toUInt32(tmp ^ toUInt32(v1 + sum) ^ toUInt32((v1 >> 5) + k1)) );

sum = toUInt32(sum - delta);

}

byte[] b0 = long_to_bytes(v0, 4);

byte[] b1 = long_to_bytes(v1, 4);

return new byte[] {b0[0], b0[1], b0[2], b0[3], b1[0], b1[1], b1[2], b1[3]};

}

/*** 将 long 类型的 n 转为 byte 数组,如果 len 为 4,则只返回低32位的4个byte

*@paramn 需要转换的long

*@paramlen 若为4,则只返回低32位的4个byte,否则返回8个byte

*@return转换后byte数组*/

private static byte[] long_to_bytes(long n, int len) {

byte a = (byte)((n & BYTE_4) >> 24);

byte b = (byte)((n & BYTE_3) >> 16);

byte c = (byte)((n & BYTE_2) >> 8);

byte d = (byte)(n & BYTE_1);

if (len == 4) {

return new byte[] {a, b, c, d};

}

byte ha = (byte)(n >> 56);

byte hb = (byte)((n >> 48) & BYTE_1);

byte hc = (byte)((n >> 40) & BYTE_1);

byte hd = (byte)((n >> 32) & BYTE_1);

return new byte[] {ha, hb, hc, hd, a, b, c, d};

}

/*** 将4个byte转为 Unsigned Integer 32,以 long 形式返回

*@parambs 需要转换的字节

*@return返回 long,高32位为0,低32位视为Unsigned Integer*/

private static long bytes_to_uint32(byte[] bs) {

return ((bs[0]<<24) & BYTE_4) +

((bs[1]<<16) & BYTE_3) +

((bs[2]<<8) & BYTE_2) +

(bs[3] & BYTE_1);

}

/*** 将long的高32位清除,只保留低32位,低32位视为Unsigned Integer

*@paramn 需要清除的long

*@return返回高32位全为0的long*/

private static long toUInt32(long n) {

return n & UINT32_MAX;

}

//-------------------------------------------------------//以下 是用于Debug的函数//-------------------------------------------------------

private static void println_array(byte[] b) {

for (byte x : b) {

System.out.printf("%02X ", x);

}

System.out.println();

}

/*private static void println_array(long[] b) {

for (long x : b) {

System.out.printf("%016X ", x);

}

System.out.println();

}*/

private static void test() {

}

public static void main(String[] args) {

//byte[] bs = new byte[] {(byte)0xFF, (byte)0xEE, (byte)0xDD, (byte)0xCC};//System.out.printf("%016X\n", bytes_to_uint32(bs));//System.out.println(bytes_to_uint32(bs));//

//

TEA t = new TEA();

byte[] pnt = new byte[] {

0x00, 0x00, 0x00, 0x20,

0x00, 0x00, 0x00, 0x10

};

byte[] k = new byte[] {

0x00, 0x00, 0x00, 0x04,

0x00, 0x00, 0x00, 0x03,

0x00, 0x00, 0x00, 0x02,

0x00, 0x00, 0x00, 0x01

};

t.setKey(k);

//byte[] enc = t.encrypt(v, k);//byte[] dec = t.decrypt(enc, k);

byte[] enc = t.encrypt_group(pnt);

//byte[] enc = new byte[] {(byte) 0xC1, (byte) 0xC6, 0x48, 0x7A, (byte) 0x9E, 0x6F, (byte) 0xF2, 0x56};

byte[] dec = t.decrypt_group(enc);

//println_array(v_from_byte_to_long(new byte[]{ 0x7F, 0x1E, 0x55, 0x56, 0x32, 0x35, 0x65, 0x78 }));//println_array(k_from_byte_to_long(new byte[]{ 0x7F, 0x1E, 0x55, 0x56, 0x32, 0x35, 0x65, 0x78, 0x6F, 0x1E, 0x55, 0x56, 0x32, 0x35, 0x65, 0x78 }));//println_array(long_to_bytes((long)0x7E987654, 8));//byte b = (byte)0xEF;//println_array(new long[] { (b << 24) & 0xFF000000L } );//println_array(new long[] {(byte)0xEF});//String[] plain = new String[32];//for (i = 0; i < 32; i++) {//plain[i] = String.//}//byte[] pnt = "123".getBytes();//byte[] enc = encrypt(pnt, k);//byte[] dec = decrypt(enc, k);

System.out.println("Key:");

println_array(k);

System.out.println("Encrypt And Decrypt:");

println_array(pnt);

println_array(enc);

println_array(dec);

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值