因为设备不能加载sun带的加密包,后经过努力寻找,总算得以实现
根据某某牛人的源码,稍加改动,以适合在java下运行
后面再将地址补上
简单实现了3DES加解密,部分功能未实现
public class Des {
public static int ENCRYPT=0;
public static int DECRYPT=1;
public static int ECB=0;
public static int CBC=1;
public static int KEY_LEN_8=8;
public static int KEY_LEN_16=16;
public static int KEY_LEN_24=24;
public static int PAD_ISO_1=0;
public static int PAD_ISO_2=1;
public static int PAD_PKCS_7=2;
static byte[]IP_Table =
{
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7
};
static byte[] IPR_Table =
{
40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25
};
static byte[] E_Table =
{
32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21,
20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29,
28, 29, 30, 31, 32, 1
};
static byte[] P_Table =
{
16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25
};
static byte[] PC1_Table =
{
57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4
};
static byte[] PC2_Table =
{
14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32
};
static byte[] LOOP_Table =
{
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1
};
static byte[][][] S_Box =
{
{
{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7},
{ 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8},
{ 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0},
{15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}
},
{
{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10},
{ 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5},
{ 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15},
{13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}
},
{
{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8},
{13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1},
{13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7},
{ 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}
},
{
{ 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15},
{13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9},
{10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4},
{ 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}
},
{
{ 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9},
{14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6},
{ 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14},
{11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}
},
{
{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11},
{10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8},
{ 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6},
{ 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}
},
{
{ 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1},
{13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6},
{ 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2},
{ 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}
},
{
{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7},
{ 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2},
{ 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8},
{ 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}
}
};
public Des() {
// TODO Auto-generated constructor stub
}
static void Memcpy(byte[]desc,byte[]source,int len)
{
int i;
for(i=0;i<len;i++)
{
desc[i]=source[i];
}
}
static void Memcpy(byte[]desc,byte[]source,int start,int len)
{
int i;
for(i=start;i<start+len;i++)
{
desc[i-start]=source[i];
}
}
static void Memcpy(byte[]desc,int pos,byte[]source,int start,int len)
{
int i;
for(i=start;i<start+len;i++)
{
desc[pos+(i-start)]=source[i];
}
}
static void Memmove(byte[]desc,byte[]source,int start,int len)
{
int i;
for(i=len;i>=start+len;i--)
{
desc[i]=source[i];
}
}
static void MemsetZero(byte[] Out,int len)
{
int i;
for(i=0;i<len;i++)Out[i]=0;
}
/*******************************************************************
函 数 名 称: ByteToBit
功 能 描 述: 把BYTE转化为Bit流
参 数 说 明: Out: 输出的Bit流[in][out]
In: 输入的BYTE流[in]
bits: Bit流的长度[in]
返回值 说明: void
*******************************************************************/
static void ByteToBit(byte[] Out, byte []In, int bits)
{
int i;
byte tmp;
for (i=0; i<bits; ++i)
{
tmp=(byte)(7-(i&7));
Out[i]=(byte)((In[i>>3]>>tmp)& 1);
}
}
/*******************************************************************
函 数 名 称: BitToByte
功 能 描 述: 把Bit转化为Byte流
参 数 说 明: Out: 输出的BYTE流[in][out]
In: 输入的Bit流[in]
bits: Bit流的长度[in]
返回值 说明: void
作 者: huangjf
更 新 日 期: 2009.6.17
*******************************************************************/
static void BitToByte(byte[] Out, byte []In, int bits)
{
int i;
int len=bits>>3;
MemsetZero(Out,len);
for (i=0; i<bits; ++i)
Out[i>>3] |= In[i]<<(7 - i&7);
}
/*******************************************************************
函 数 名 称: RotateL
功 能 描 述: 把BIT流按位向左迭代
参 数 说 明: In: 输入的Bit流[in][out]
len: Bit流的长度[in]
loop: 向左迭代的长度
返回值 说明: void
作 者: huangjf
更 新 日 期: 2009.6.17
*******************************************************************/
static void RotateL(byte[] In, int len, int loop)
{
byte szTmp[] = new byte[256];
if (len >= 256) return;
if (loop==0 || loop>=256) return;
MemsetZero(szTmp,256);
Memcpy(szTmp, In,loop);
Memcpy(In, In,loop, len-loop);
Memcpy(In,len-loop,szTmp,0,loop);
}
/*******************************************************************
函 数 名 称: Xor
功 能 描 述: 把两个Bit流进行异或
参 数 说 明: InA: 输入的Bit流[in][out]
InB: 输入的Bit流[in]
loop: Bit流的长度
返回值 说明: void
作 者: huangjf
更 新 日 期: 2009.6.17
*******************************************************************/
static void Xor(byte[] InA, byte[] InB, int len)
{
int i;
for (i=0; i<len; ++i) InA[i] ^= InB[i];
}
/*******************************************************************
函 数 名 称: Transform
功 能 描 述: 把两个Bit流按表进行位转化
参 数 说 明: Out: 输出的Bit流[out]
In: 输入的Bit流[in]
Table: 转化需要的表指针
len: 转化表的长度
返回值 说明: void
作 者: huangjf
更 新 日 期: 2009.6.17
*******************************************************************/
static void Transform(byte[] Out, byte[] In, byte[] Table, int len)
{
byte szTmp[] = new byte[256];
int i;
if ((Out.length==0) || (In.length==0) || (Table.length==0)) return;
if (len >= 256) return;
MemsetZero(szTmp,256);
for (i=0; i<len; ++i) szTmp[i] = In[Table[i]-1]; //按照Table表取出指定位的值存于szTmp[i]内
Memcpy(Out,szTmp,len); //得到56位数
}
/*******************************************************************
函 数 名 称: S_func
功 能 描 述: 实现数据加密S BOX模块
参 数 说 明: Out: 输出的32Bit[out]
In: 输入的48Bit[in]
返回值 说明: void
作 者: huangjf
更 新 日 期: 2009.6.17
*******************************************************************/
static void S_func(byte[] Out, byte[] In)
{
int i,j,k,l;
for (i=0,j=0,k=0; i<8; ++i)
{
//将B[J]的第1位和第6位组合为一个2位长度的变量M,M作为在S[J]中的行号
j = (In[i*6]<<1) + In[i*6+5];
//将B[J]的第2位到第5位组合,作为一个4位长度的变量N,N作为在S[J]中的列号
k = (In[i*6+1]<<3) + (In[i*6+2]<<2) + (In[i*6+3]<<1) + In[i*6+4];
for ( l=0; l<4; ++l)
{
Out[i*4+l]=(byte)(((S_Box[i][j][k])>>(byte)(3 - l))& 1);
}
}
}
/*******************************************************************
函 数 名 称: F_func
功 能 描 述: 实现数据加密到输出P
参 数 说 明: Out: 输出的32Bit[out]
In: 输入的48Bit[in]
返回值 说明: void
作 者: huangjf
更 新 日 期: 2009.6.17
*******************************************************************/
static void F_func(byte[] In, byte[] Ki)
{
byte[] MR=new byte[48];
MemsetZero(MR,48);
//将数据按E_Table位顺序进行存放得出48位数据
Transform(MR, In, E_Table, 48);
Xor(MR, Ki, 48); //将数据与密钥进行48位异或
S_func(In, MR); //将加密后的密钥对In数据进行加密
Transform(In, In, P_Table, 32); //将加密后的数据按P_Table的位顺序表进行存放并获得32位数据
}
/*******************************************************************
函 数 名 称: SetSubKey
功 能 描 述: 变换(换位)8字节密钥,生成16个子密钥
参 数 说 明: pSubKey: 转换生成的16个子密钥[out]
Key: 输入的8字节64Bit密钥[in]
返回值 说明: void
作 者: huangjf
更 新 日 期: 2009.6.17
*******************************************************************/
static void SetSubKey(byte[][] pSubKey, byte[] Key)
{
int i;
byte[] K=new byte[64];
byte[] KL=new byte[28];
byte[] KR=new byte[28];
// 将密钥转为位存储
ByteToBit(K, Key, 64);
//去除密钥每字节的最后一位,得到56位数
Transform(K, K, PC1_Table, 56);
Memcpy(KL,K,0,28);
Memcpy(KR,K,28,28);
for ( i=0; i<16; ++i)
{
RotateL(KL, 28, LOOP_Table[i]); //根据LOOP_Table表对应位数对前28位进行左移
RotateL(KR, 28, LOOP_Table[i]); //根据LOOP_Table表对应位数对后28位进行左移
Memcpy(K,KL,0,28);
Memcpy(K,28,KR,0,28);
Transform(pSubKey[i], K, PC2_Table, 48); //左移后将密钥按照PC2_Table表进行存放,得到48位密钥
}
//得到16组48位的子密钥
}
/*******************************************************************
函 数 名 称: DES
功 能 描 述: 处理8字节64位的数据
参 数 说 明: Out: 输出的8字节[out]
In: 输入的8字节待加密[in]
pSubKey: 转换后的16个48位子密钥
Type: 类型:加密ENCRYPT,解密DECRYPT
返回值 说明: void
作 者: huangjf
更 新 日 期:2009.6.17
*******************************************************************/
static void DES(byte[] Out, byte[] In, byte[][] pSubKey, int Type)
{
int i;
byte[] M=new byte[64];
byte[] ML=new byte[32];
byte[] MR=new byte[32];
byte[] szTmp=new byte[32];
ByteToBit(M, In, 64); //将数据转为位
Transform(M, M, IP_Table, 64); //将数据按IP_Table表进行位存放
Memcpy(ML,M,32);
Memcpy(MR,M,32,32);
if (Type == ENCRYPT)
{
for (i=0; i<16; ++i)
{
Memcpy(szTmp, MR, 32);
F_func(MR, pSubKey[i]);
Xor(MR, ML, 32);
Memcpy(ML, szTmp, 32);
}
}
else
{
for (i=15; i>=0; --i)
{
Memcpy(szTmp, MR, 32);
F_func(MR, pSubKey[i]);
Xor(MR, ML, 32);
Memcpy(ML, szTmp, 32);
}
}
Memcpy(M,ML,32);
Memcpy(M,32,MR,0,32);
RotateL(M, 64, 32); //进行左32位和右32位调换一下位置
Transform(M, M, IPR_Table, 64);
BitToByte(Out, M, 64);
}
/*******************************************************************
函 数 名 称: Run3Des
功 能 描 述: 执行3DES算法对文本加解密
参 数 说 明: bType :类型:加密ENCRYPT,解密DECRYPT
bMode :模式:ECB,CBC
In :待加密串指针
in_len :待加密串的长度,同时Out的缓冲区大小应大于或者等于in_len
Key :密钥(可为8位,16位,24位)支持3密钥
key_len :密钥长度,多出24位部分将被自动裁减
Out :待输出串指针
out_len :输出缓存大小
cvecstr :8字节随即字符串
返回值 说明: int :是否加密成功,1:成功,0:失败
作 者: huangjf
更 新 日 期: 2009.6.17
3DES(加密) = DES(key1, 加密) DES(key2, 解密) DES(key3, 加密)
3DES(解密) = DES(key3, 解密) DES(key2, 加密) DES(key1, 解密)
每个KEY为64位,总共可以有192位的KEY, 但一般都只使用128位的key
如果只用128位密钥,则key3 = key1
*******************************************************************/
public static int Run3Des(int bType, int bMode, byte[] In,int in_len, byte[] Key, int key_len, byte[] Out, int out_len, byte[] cvecstr)
{
int i,j,k;
byte m_SubKey[][][]=new byte[3][16][48];
byte m_Key[]=new byte[8];
byte m_Out[]=new byte[8];
byte m_In[]=new byte[8];
int nKey;
/*参数不合法*/
if ((In.length==0)||(Key.length==0) || (Out.length==0)) return 0;
/*被加密数据长度,必需为8字节的倍数,如果非8的倍数,调用RunPad()函数补位*/
if ((((byte)in_len) & 0x00000007)>0) return 0;
/*密钥长度,3DES只支持8、16、24字节(192位的密钥,实际使用128位,每个第8位作为奇偶校验位),多于24字节的自动裁剪*/
if ((((byte)key_len) & 0x00000007)>0) return 0;
/*输出缓存大小判断*/
if (out_len < in_len) return 0;
/*生成16个子密钥*/
nKey = (key_len>>3)>3 ? 3 : (key_len>>3); //判断密钥个数,1,2,3
for(i=0;i<3;i++)
{
for(j=0;j<16;j++)
{
MemsetZero(m_SubKey[i][j],48);
}
}
for ( i=0; i<nKey; i++)
{
//对三种密钥进行处理
Memcpy(m_Key,Key,i<<3,8);
SetSubKey(m_SubKey[i], m_Key);
}
if (bMode == ECB)
{
if (nKey == 1) //1DES
{
/*每8字节加密*/
for (i=0,j=in_len>>3; i<j; ++i)
{
Memcpy(m_Out,Out,i*8,8);
Memcpy(m_In,In,i*8,8);
DES(m_Out, m_In, m_SubKey[0], bType);
}
}
else if (nKey == 2) //2DES
{
for (i=0,j=in_len>>3; i<j; ++i)
{
Memcpy(m_Out,Out,i*8,8);
Memcpy(m_In,In,i*8,8);
DES(m_Out, m_In, m_SubKey[0], bType);
DES(m_Out, m_Out, m_SubKey[1], bType==ENCRYPT?DECRYPT:ENCRYPT);
DES(m_Out, m_Out, m_SubKey[0], bType);
}
}
else if (nKey == 3) //3DES
{
for (i=0,j=in_len>>3; i<j; ++i)
{
Memcpy(m_Out,Out,i*8,8);
Memcpy(m_In,In,i*8,8);
DES(m_Out, m_In, m_SubKey[bType==DECRYPT?2:0], bType);
DES(m_Out, m_Out, m_SubKey[1], bType==ENCRYPT?DECRYPT:ENCRYPT);
DES(m_Out, m_Out, m_SubKey[bType==DECRYPT?0:2], bType);
}
Memcpy(Out,m_Out,8);
}
else
{
/*密钥长度不对*/
return 0;
}
}
else if (bMode == CBC)
{
/*if (cvecstr == NULL) return 0;
char cvec[8] = {0};
char cvin[8] = {0};
memcpy(cvec, cvecstr, 8);
if (nKey == 1)
{
for (i=0,j=in_len>>3; i<j; ++i,Out+=8,In+=8)
{
if (bType == ENCRYPT)
{
for (k=0; k<8; ++k)
{
cvin[k] = In[k] ^ cvec[k];
}
}
else
{
memcpy(cvin, In, 8);
}
DES(Out, cvin, &m_SubKey[0], bType);
if (bType == ENCRYPT)
{
memcpy(cvec, Out, 8);
}
else
{
for (k=0; k<8; ++k)
{
Out[k] = Out[k] ^ cvec[k];
}
memcpy(cvec, cvin, 8);
}
}
}
else if (nKey == 2)
{
for (i=0,j=in_len>>3; i<j; ++i,Out+=8,In+=8)
{
if (bType == ENCRYPT)
{
for ( k=0; k<8; ++k)
{
cvin[k] = In[k] ^ cvec[k];
}
}
else
{
memcpy(cvin, In, 8);
}
DES(Out, cvin, &m_SubKey[0], bType);
DES(Out, Out, &m_SubKey[1], bType==ENCRYPT?DECRYPT:ENCRYPT);
DES(Out, Out, &m_SubKey[0], bType);
if (bType == ENCRYPT)
{
memcpy(cvec, Out, 8);
}
else
{
for (k=0; k<8; ++k)
{
Out[k] = Out[k] ^ cvec[k];
}
memcpy(cvec, cvin, 8);
}
}
}
else if (nKey == 3)
{
for (i=0,j=in_len>>3; i<j; ++i,Out+=8,In+=8)
{
if (bType == ENCRYPT)
{
for (k=0; k<8; ++k)
{
cvin[k] = In[k] ^ cvec[k];
}
}
else
{
memcpy(cvin, In, 8);
}
DES(Out, cvin, &m_SubKey[bType?2:0], bType);
DES(Out, Out, &m_SubKey[1], bType==ENCRYPT?DECRYPT:ENCRYPT);
DES(Out, Out, &m_SubKey[bType?0:2], bType);
if (bType == ENCRYPT)
{
memcpy(cvec, Out, 8);
}
else
{
for (k=0; k<8; ++k)
{
Out[k] = Out[k] ^ cvec[k];
}
memcpy(cvec, cvin, 8);
}
}
}
else
{
//密钥长度不对
return 0;
} */
}
else
{
return 0;
}
return 1;
}
}
//函数调用
public static void main(String[] args) {
// TODO Auto-generated method stub
byte[] Key = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24};
byte[] FVin = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, (byte)0x99};
byte[] FVout = new byte[8];
byte[] FCvec = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37};
//ECB加密
if (Des.Run3Des(Des.ENCRYPT, Des.ECB, FVin, 8, Key, Des.KEY_LEN_24, FVout, 8, FVout) == 1)
{
String tmpStr = "";
for (int i=0; i<8; i++)
{
tmpStr = tmpStr +" "+ Integer.toHexString(FVout[i] & 0xFF );
}
System.out.println(tmpStr);
}
//ECB解密
if (Des.Run3Des(Des.DECRYPT, Des.ECB, FVout, 8, Key, Des.KEY_LEN_24, FVout, 8, FVout) == 1)
{
String tmpStr = "";
for (int i=0; i<8; i++)
{
tmpStr = tmpStr +" "+ Integer.toHexString(FVout[i] & 0xFF );
}
System.out.println(tmpStr);
}
}