123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279 |
- package com.inet.ailink.receiver.common.utils;
-
- import com.inet.ailink.receiver.common.enums.Common;
-
- import java.io.UnsupportedEncodingException;
-
- public class TeaUtils {
-
- public static byte[] encrypt(byte[] data, byte[] key) {
- int data_len = data.length; // 数据的长度
- if (data_len == 0) {
- return new byte[] {};
- }
- TeaUtils t = new TeaUtils();
- 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;
- int result_len = data_len;
- 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];
- result[i + k ] = 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];
- result[dlen + k] = 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[] {};
- // }
- TeaUtils t = new TeaUtils();
- if (!t.setKey(key)) {
- return new byte[] {};
- }
- //int data_len = data.length - 1, dlen; // 数据的长度
- int data_len = data.length, dlen; // 数据的长度
- dlen = data_len;
- //int residues = (int)(data[0]); // 余数
- // if (residues > 0) {
- // dlen = data_len - group_len;
- // } else {
- // dlen = data_len;
- // }
-
- //byte[] result = new byte[dlen + residues];
- byte[] result = new byte[dlen];
-
- 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];
- enc[j] = data[i + j];
- }
- 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;
- }
-
-
- /**
- * 设置密钥
- * @param k 密钥
- * @return 密钥长度为16个byte时, 设置密钥并返回true,否则返回false
- */
- public boolean setKey(byte[] k) {
- if(k==null){
- k = Common.TEA_KEY;
- }
- 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轮
- * @param loops 加密轮数
- * @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 static long k0;
- private static long k1;
- private static long k2;
- private static long k3;
-
- private static int loops = 32;
-
- /**
- * 加密一组明文
- * @param v 需要加密的明文
- * @return 返回密文
- */
- public static 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]};
- }
-
- /**
- * 解密一组密文
- * @param v 要解密的密文
- * @return 返回明文
- */
- public static 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
- * @param n 需要转换的long
- * @param len 若为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 形式返回
- * @param bs 需要转换的字节
- * @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
- * @param n 需要清除的long
- * @return 返回高32位全为0的long
- */
- private static long toUInt32(long n) {
- return n & UINT32_MAX;
- }
-
- public static void main(String args[]) throws UnsupportedEncodingException
- {
- TeaUtils t = new TeaUtils();
- t.setKey(Common.TEA_KEY);
- byte[] old = new byte[]{(byte)0x01,(byte)0x16,(byte)0xA4,(byte)0x28,
- (byte)0x32,(byte)0x18,(byte)0x4A,(byte)0x88,
- (byte)0x00,(byte)0x00 ,(byte)0x00 ,(byte)0x00,
- (byte)0x00 ,(byte)0x00 ,(byte)0x42 ,(byte)0x4D,
- (byte)0x10 ,(byte)0x01,(byte)0x0A ,(byte)0x00,
- (byte)0x13 ,(byte)0x05 ,(byte)0x07 ,(byte)0xC8};
- /*byte[] old = new byte[] {
- 0x00, 0x00, 0x00, 0x20,
- 0x00, 0x00, 0x00, 0x10
- };*/
-
- byte[] enc = t.encrypt(old,Common.TEA_KEY);
- System.out.println( "tea加密:");
- for(byte i : enc)
- System.out.print(i + " ");
- System.out.println();
-
- byte[] dec = t.decrypt(enc,Common.TEA_KEY);
- System.out.println( "tea解密:");
- for(byte i : dec)
- System.out.print(i + " ");
- System.out.println();
- }
- }
|