主要分为两部分 加解密部分和编解码部分涉及两个文件1,tea.java 2,hex2byte.java
/******************************************tea.java*****************************/
package javaTEA;
import java.io.UnsupportedEncodingException;
public class tea {
private static int n=6;//密钥生成参数之一 从原始密钥字符串第 n位生成加密密钥
/**
* 原始加密函数
* @param v长度为2个32位数据
* @param k 加密密钥 为4个 32位数据
* @param rounds 加密轮数 16或32
* @return 加密后密文数据 两个32位数据
*/
private static int[] en(int[] v,int[] k,int rounds){
int y=v[0],z=v[1],sum=0,delta=0x9E3779B9,
a=k[0],b=k[1],c=k[2],d=k[3];
int[] o=new int[2];
while(rounds-->0){
sum+=delta;
y+=((z << 4)+a)^(z+sum)^((z >>> 5)+b);
z+=((y << 4)+c)^(y+sum)^((y >>> 5)+d);
}
o[0]=y;
o[1]=z;
return o;
}
/**
* 原始解密函数
* @param v长度为2个32位数据
* @param k 加密密钥 为4个 32位数据
* @param rounds 加密轮数 16或32
* @return 解密后密文数据 两个32位数据
*/
private static int[] de(int[] v,int[] k,int rounds){
int y=v[0],z=v[1],sum=0,
delta=0x9E3779B9,a=k[0],b=k[1],c=k[2],d=k[3];
if(rounds==32)
sum=0xc6ef3720;
else
sum=0xe3779b90;
int[] o=new int[2];
while(rounds-->0){
z-=((y << 4)+c)^(y+sum)^((y >>> 5)+d);
y-=((z << 4)+a)^(z+sum)^((z >>> 5)+b);
sum-=delta;
}
o[0]=y;
o[1]=z;
return o;
}
/**
* 将byte数组使用“:”相连成字符串
* @param a 待处理byte数组
* @return 处理后String
*/
/*private static String byte2String(byte[] a){
String byteStr = new String();
for(int i=0;i<a.length;i++)
{
byteStr+=String.valueOf(a[i]);
if(i!=a.length-1)
byteStr+=":";
}
return byteStr;
}*/
/**
* 加如标识符函数,在经过加密后的密文前8byte 加入标识符
* @param orignal 需要加入标识符的原始密文bye[]数组
* @return 经过加入标识符后的密文
*/
private static byte[] flag(byte[] orignal){
byte[] o=new byte[orignal.length+8];
byte[] flag=new byte[]{0x7d,0x7d,0x7d,0x7d,0x7d,0x7d,0x7d,0x7d};
System.arraycopy(flag, 0, o, 0, flag.length);
System.arraycopy(orignal, 0, o, flag.length, orignal.length);
return o;
}
/**
* 去除表示符函数
* @param orignal 需要进行处理的原始密文
* @return 去除标识符的密文
*/
private static byte[] unflag(byte[] orignal){
byte[] o=new byte[orignal.length-8];
System.arraycopy(orignal, 8, o, 0, orignal.length-8);
return o;
}
/**
* 表示符比较函数 鉴定一个字符串是否含有标识符
* @param content 需要进行鉴定的字符串
* @return 返回1 则代表含有相同的标识符 否则表示和预定义的标识符不同
*/
private static int flag_compare(byte[] content){
byte[] flag=new byte[]{0x7d,0x7d,0x7d,0x7d,0x7d,0x7d,0x7d,0x7d};
int i;
for(i=0;i<8;i++)
{
if(content[i]!=flag[i])
return 0;
}
return 1;
}
/**
* 经过封装后的加密函数
* @param content byte[] 明文byte数组
* @param key byte[] 密钥bate[]数组
* @return byte[] 经过加密且含有标识符的密文byte数组
*/
public static byte[] encrypt(byte[] content, byte[] key,int rounds) {
if (content == null || key == null || content.length == 0 ||
key.length == 0) {
return null;
}
byte[] result = null;
int resultLength = content.length;
int mol = resultLength % 8; //
if (mol != 0) {
resultLength = resultLength + 8 - mol; //计算 密文长度
}
int[] k = validateKey3(key); // 设置密钥
int[] v = new int[2];
int[] o = null;
result = new byte[resultLength];
int convertTimes = resultLength - 8; //对前 n*8byte 加密
int next = 0;
int times = 0;
// 分块进行加密
for (; times < convertTimes; times += 8) {
next = times + 4;
v[0] = byte2int(content, times);
v[1] = byte2int(content, next);
o = en(v, k,rounds);
int2byte(o[0], result, times);
int2byte(o[1], result, next);
}
next = times + 4;
if (mol != 0) { // 最后8byte加密
byte[] tmp = new byte[8];
System.arraycopy(content, times, tmp, 0, mol);//不满则补0
v[0] = byte2int(tmp, 0);
v[1] = byte2int(tmp, 4);
o = en(v, k,rounds);
int2byte(o[0], result, times);
int2byte(o[1], result, next);
}
else {
v[0] = byte2int(content, times);
v[1] = byte2int(content, next);
o = en(v, k,rounds);
int2byte(o[0], result, times);
int2byte(o[1], result, next);
}
return flag(result);
//return byte2String(flag(result));
}
/**
* 封装后揭秘函数
* @param content byte[] 待解密byte密文数组 若输入不为密文 则返回原文
* @param key byte[] 解密密钥和加密函数相同
* @return byte[] 解密后密文
*/
public static byte[] decrypt(byte[] scontent, byte[] key,int rounds) {
if(flag_compare(scontent)==1){
byte[] content=unflag(scontent);
if(content==null||key==null||content.length==0||key.length==0){
return content;
}
if (content.length % 8 != 0) {
throw new IllegalArgumentException("Content cannot be decypted!");
}
byte[] result = null;
int[] k = validateKey3(key); // 密钥设置 函数 见之后说明
int[] v = new int[2];
int[] o = null;
result = new byte[content.length];
int convertTimes = content.length;
int next = 0;
int times = 0;
for (; times < convertTimes; times += 8) { // 分块加密
next = times + 4;
v[0] = byte2int(content, times);
v[1] = byte2int(content, next);
o = de(v, k,rounds);
int2byte(o[0], result, times);
int2byte(o[1], result, next);
}
// 去掉空白
convertTimes = convertTimes-8;
for(times=convertTimes+1;times<content.length;times++){
if(result[times]==(byte)0)break;
}
byte[] tmp=result;
result = new byte[times];
System.arraycopy(tmp,0,result,0,times); // 复制非空区域
return result;
}
else
return scontent;
}
/**
*将四个8位数字转换为一个32位数据
* @param buf byte[] 存储需要转换的byte数组
* @param offset 开始转换位置
* @return一个32位的数字
*/
private static int byte2int(byte[] buf, int offset) {
return
( buf[offset + 3] & 0x000000ff) |
((buf[offset + 2] & 0x000000ff) << 8) |
((buf[offset + 1] & 0x000000ff) << 16) |
((buf[offset ] & 0x000000ff) << 24);
}
/**
* 一个32位数字转换为4个byte型数据
* @param integer 需要进行转换的32位数据
* @param buf byte[] 需要存储byte数据的数组
* @param offset 存储起始位置ַ
*/
private static void int2byte(int integer, byte[] buf, int offset) {
buf[offset ] = (byte)(integer >> 24);
buf[offset + 1] = (byte)(integer >> 16);
buf[offset + 2] = (byte)(integer >> 8);
buf[offset + 3] = (byte) integer;
}
/**密钥设定函数 选取16位byte型作为前8byte加密密钥 从原始字符串中第n位开始取8byte 若不满8byte 补零 之后8byte补位 为127-n-i
*
* @param key 原始输入的密钥字符串
* @return 返回加解密密钥
*/
private static int[] validateKey3(byte[] key){
byte[] tempkey=new byte[16];
if(key.length-n+1<8){
System.arraycopy(key, n-1, tempkey, 0, key.length-n+1);
for(int i=8;i<16;i++)
tempkey[i]=(byte)(127-n-i);
int k[]=new int[]{
byte2int(tempkey, 0),
byte2int(tempkey, 4),
byte2int(tempkey, 8),
byte2int(tempkey, 12)
};
return k;
}
else{
System.arraycopy(key, n-1, tempkey, 0, 8);
for(int i=8;i<16;i++)
tempkey[i]=(byte)(127-n-i);
int k1[]=new int[]{
byte2int(tempkey, 0),
byte2int(tempkey, 4),
byte2int(tempkey, 8),
byte2int(tempkey, 12)
};
return k1;
}
}
/**
* 将byte[]数组转换为hex字符串功能的加密函数
*/
public static String hex_en(byte[] content,byte[] key,int rounds){
return hex2byte.bytetohex(encrypt(content,key,rounds));
}
/**
* 将hex加密字符串解密函数
* @throws UnsupportedEncodingException
*/
public static String hex_de(String content,byte[] key,int rounds) throws UnsupportedEncodingException{
return new String(decrypt(hex2byte.hextobyte(content),key,rounds),"utf-8");
}
/*public static String Base64_en(byte[] content,byte[] key,int rounds){
return Base64.encode(encrypt(content,key,rounds));
}
/**对经过base64编码的秘闻进行解密额函数
*
* @param content
* @param key
* @param rounds
* @return
*/
/*public static byte[] Base64_de(String content,byte[] key,int rounds){
return decrypt(Base64.decode(content),key,rounds);
}*/
/**
* �ӵ�nλ��ʼȡ�����16byte��Ϊ������Կ �����������㣬������������
* @param key��Կbyte����
* @return 4λint����Կ����
*/
/* private static int[] validateKey2(byte[] key){
byte[] tempkey1=new byte[16];
if(key.length-n+1<16)
{
System.arraycopy(key, n-1, tempkey1, 0, key.length-n+1);
int k[]=new int[]{
byte2int(tempkey1, 0),
byte2int(tempkey1, 4),
byte2int(tempkey1, 8),
byte2int(tempkey1, 12)
};
return k;
}
else
{
int[] k1 = new int[] {
byte2int(key, n-1),
byte2int(key, n+3),
byte2int(key, n+7),
byte2int(key, n+11)
};
return k1;
}
}*/
/**
* У����Կ,�������16�ֽ���ĩβ����ֽ�0����16�ֽ�,�������16�ֽ�����ĩβ������ֽ�
* @param key byte[]
* @return int[] ����Ϊ4�����ֽ���������
* @throws UnsupportedEncodingException
*/
/* private static int[] validateKey(byte[] key) {
byte[] tmpkey = key;
if (key.length < 16) { // ����16�ֽ�����0����,Ҳ����ʹ���������õķ�������
tmpkey = new byte[16];
System.arraycopy(key, 0, tmpkey, 0, key.length);
}
int[] k = new int[] {
byte2int(tmpkey, 0),
byte2int(tmpkey, 4),
byte2int(tmpkey, 8),
byte2int(tmpkey, 12)
};
return k;
}*/
//测试
public static void main(String[] args) throws UnsupportedEncodingException {
//String initstr = "{\"result\":{\"code\":\"2003\",\"msg\":\"json error\"}}";
String initstr = "{ \"system\": { \"ipp\": \"2.0\", \"ver\": \"1.0\", \"lang\": \"en\", \"key\": \"1k8VKDqpOMndSxtDhrExYtTAsV\" }, \"request\": { \"user\": { \"userName\": \"13700000000\", \"token\": \"sjk12ks1kl\", \"pkgName\": \"com.ipp.xx.xx\", \"devType\": \"0\", \"familyId\": 12 }, \"device\": { \"id } } }";
//String initstr = "thisisjiaoiloveyou";
String key = "chdevicecloud";
// System.out.print("bytekey=");
// byte[] byetkey = key.getBytes("utf-8");
// for(int i=0;i<byetkey.length;i++)
// System.out.print(" "+byetkey[i]);
// System.out.println();
// System.out.print("bytecon=");
// byte[] bytecon = initstr.getBytes("utf-8");
// for(int i=0;i<bytecon.length;i++)
// System.out.print(" "+bytecon[i]);
// System.out.println();
//
//
//
//
//
// byte[] enc = encrypt(bytecon,byetkey,16);
// for(int i=0;i<enc.length;i++)
// System.out.print(" "+enc[i]);
// System.out.println();
System.out.println("发送报文:"+initstr);
// byte[] nn=encrypt(initstr.getBytes("utf-8"),key.getBytes("utf-8"),32);
// System.out.println(" yyy"+new String(encrypt(initstr.getBytes("utf-8"),key.getBytes("utf-8"),32),"utf-8"));
String ss=hex_en(initstr.getBytes("utf-8"),key.getBytes("utf-8"),16);
System.out.println("发送报文加密:"+ss);
String st="7D7D7D7D7D7D7D7DCF48BCD007B45771DC6C815FCB995328A7E19A1125B0C5B6FDC10EE6C81BDB3971F77C5D21AD140F6A56AF9F0B6CCBC6990FE28C9D7F9ADE";
String sss=hex_de(ss,key.getBytes("utf-8"),16);
System.out.println("发送报文解密:"+sss);
//int[] bytekey=validateKey3(key.getBytes("utf-8"));
//for(int i=0;i<bytekey.length;i++)
//System.out.print(" "+bytekey[i]);
//System.out.println();
}
}
/***********************************************hex2byte.java*******************************/
package javaTEA;
//import java.io.UnsupportedEncodingException;
public class hex2byte {
public static String bytetohex(byte[] bt){
int len = bt.length;
char[] out=new char[2*bt.length] ;
for(int i=0,j=0;j<len;i+=2,j++){
char temps1 =(char)('0'+ ((bt[j] & 0xf0)>>4));
//System.out.print(temps1);
char temps2 = (char)('0' + (bt[j] & 0x0f));
if(temps1>'9'||temps1<'0'){
switch (temps1-'9'){
case 1: temps1='A';break;
case 2: temps1='B';break;
case 3: temps1='C';break;
case 4: temps1='D';break;
case 5: temps1='E';break;
case 6: temps1='F';break;
}
}
if(temps2>'9'||temps2<'0'){
switch (temps2-'9'){
case 1: temps2='A';break;
case 2: temps2='B';break;
case 3: temps2='C';break;
case 4: temps2='D';break;
case 5: temps2='E';break;
case 6: temps2='F';break;
}
}
out[i]=temps1;
//System.out.print(out[i]);
out[i+1]=temps2;
//System.out.print(out[i+1]);
}
//System.out.println();
return new String(out);
}
public static byte[] hextobyte(String hex){
byte[] out = new byte[hex.length()/2];
//System.out.println("strlen="+hex.length());
int s = 0,s1=0;
for(int j = 0,i=0;i<hex.length()/2;i++,j+=2){
if('0'>hex.charAt(j)||hex.charAt(j)>'9'){
switch (hex.charAt(j)){
case 'A': s=10;break;
case 'B': s=11;break;
case 'C': s=12;break;
case 'D': s=13;break;
case 'E': s=14;break;
case 'F': s=15;break;
}
}
else s=hex.charAt(j)-'0';
if('0'>hex.charAt(j+1)||hex.charAt(j+1)>'9'){
switch (hex.charAt(j+1)){
case 'A': s1=10;break;
case 'B': s1=11;break;
case 'C': s1=12;break;
case 'D': s1=13;break;
case 'E': s1=14;break;
case 'F': s1=15;break;
}
}
else s1=hex.charAt(j+1)-'0';
out[i]=(byte) ( (s&0x0000000f)<<4|(s1&0x0000000f));
}
return out;
}
}
TEA算法多语言实现——Java
最新推荐文章于 2023-03-10 22:13:02 发布