package
com.joker.utils;
import
java.io.UnsupportedEncodingException;
public
class
DESedeTool {
/***************************** 压缩替换S-Box�? **************************************************/
private
static
final
int
[][] s1 = {
{
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
} };
private
static
final
int
[][] s2 = {
{
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
} };
private
static
final
int
[][] s3 = {
{
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
} };
private
static
final
int
[][] s4 = {
{
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
},
// erorr
{
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
} };
private
static
final
int
[][] s5 = {
{
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
} };
private
static
final
int
[][] s6 = {
{
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
} };
private
static
final
int
[][] s7 = {
{
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
} };
private
static
final
int
[][] s8 = {
{
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
} };
private
static
final
int
[] ip = {
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
};
private
static
final
int
[] _ip = {
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
};
// 每次密钥循环左移位数
private
static
final
int
[] LS = {
1
,
1
,
2
,
2
,
2
,
2
,
2
,
2
,
1
,
2
,
2
,
2
,
2
,
2
,
2
,
1
};
private
static
int
[][] subKey =
new
int
[
16
][
48
];
private
static
int
HEX =
0
;
private
static
int
ASC =
1
;
/**
*
* 将十六进制A--F转换成对应数�?
*
* @param ch
*
* @return
*
* @throws Exception
*/
public
static
int
getIntByChar(
char
ch)
throws
Exception {
char
t = Character.toUpperCase(ch);
int
i =
0
;
switch
(t) {
case
'0'
:
case
'1'
:
case
'2'
:
case
'3'
:
case
'4'
:
case
'5'
:
case
'6'
:
case
'7'
:
case
'8'
:
case
'9'
:
i = Integer.parseInt(Character.toString(t));
break
;
case
'A'
:
i =
10
;
break
;
case
'B'
:
i =
11
;
break
;
case
'C'
:
i =
12
;
break
;
case
'D'
:
i =
13
;
break
;
case
'E'
:
i =
14
;
break
;
case
'F'
:
i =
15
;
break
;
default
:
throw
new
Exception(
"getIntByChar was wrong"
);
}
return
i;
}
/**
*
* 将字符串转换成二进制数组
*
* @param source
* : 16字节
*
* @return
*/
public
static
int
[] string2Binary(String source) {
int
len = source.length();
int
[] dest =
new
int
[len *
4
];
char
[] arr = source.toCharArray();
for
(
int
i =
0
; i < len; i++) {
int
t =
0
;
try
{
t = getIntByChar(arr[i]);
// System.out.println(arr[i]);
}
catch
(Exception e) {
e.printStackTrace();
}
String[] str = Integer.toBinaryString(t).split(
""
);
int
k = i *
4
+
3
;
for
(
int
j = str.length -
1
; j >
0
; j--) {
dest[k] = Integer.parseInt(str[j]);
k--;
}
}
return
dest;
}
/**
*
* 返回x的y次方
*
* @param x
*
* @param y
*
* @return
*/
public
static
int
getXY(
int
x,
int
y) {
int
temp = x;
if
(y ==
0
)
x =
1
;
for
(
int
i =
2
; i <= y; i++) {
x *= temp;
}
return
x;
}
/**
*
* s�?位长度的二进制字符串
*
* @param s
*
* @return
*/
public
static
String binary2Hex(String s) {
int
len = s.length();
int
result =
0
;
int
k =
0
;
if
(len >
4
)
return
null
;
for
(
int
i = len; i >
0
; i--) {
result += Integer.parseInt(s.substring(i -
1
, i)) * getXY(
2
, k);
k++;
}
switch
(result) {
case
0
:
case
1
:
case
2
:
case
3
:
case
4
:
case
5
:
case
6
:
case
7
:
case
8
:
case
9
:
return
""
+ result;
case
10
:
return
"A"
;
case
11
:
return
"B"
;
case
12
:
return
"C"
;
case
13
:
return
"D"
;
case
14
:
return
"E"
;
case
15
:
return
"F"
;
default
:
return
null
;
}
}
/**
*
* 将int转换成Hex
*
* @param i
*
* @return
*
* @throws Exception
*/
public
static
String int2Hex(
int
i) {
switch
(i) {
case
0
:
case
1
:
case
2
:
case
3
:
case
4
:
case
5
:
case
6
:
case
7
:
case
8
:
case
9
:
return
""
+ i;
case
10
:
return
"A"
;
case
11
:
return
"B"
;
case
12
:
return
"C"
;
case
13
:
return
"D"
;
case
14
:
return
"E"
;
case
15
:
return
"F"
;
default
:
return
null
;
}
}
/**
*
* 将二进制字符串转换成十六进制字符�?
*
* @param s
*
* @return
*/
public
static
String binary2ASC(String s) {
String str =
""
;
int
ii =
0
;
int
len = s.length();
// 不够4bit左补0
if
(len %
4
!=
0
) {
while
(ii <
4
- len %
4
) {
s =
"0"
+ s;
}
}
for
(
int
i =
0
; i < len /
4
; i++) {
str += binary2Hex(s.substring(i *
4
, i *
4
+
4
));
}
return
str;
}
/**
*
* IP初始置换
*
* @param source
*
* @return
*/
public
static
int
[] changeIP(
int
[] source) {
int
[] dest =
new
int
[
64
];
for
(
int
i =
0
; i <
64
; i++) {
dest[i] = source[ip[i] -
1
];
}
return
dest;
}
/**
*
* IP-1逆置�?
*
* @param source
*
* @return
*/
public
static
int
[] changeInverseIP(
int
[] source) {
int
[] dest =
new
int
[
64
];
for
(
int
i =
0
; i <
64
; i++) {
dest[i] = source[_ip[i] -
1
];
}
return
dest;
}
/**
*
* �?2bit扩展�?8bit
*
* @param source
*
* @return
*/
public
static
int
[] expend(
int
[] source) {
int
[] ret =
new
int
[
48
];
int
[] temp = {
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
};
for
(
int
i =
0
; i <
48
; i++) {
ret[i] = source[temp[i] -
1
];
}
return
ret;
}
/**
*
* �?8bit压缩�?2bit
*
* @param source
* (48bit)
*
* @return R(32bit)
*
* B=E(R)⊕K,将48 位的B 分成8 个分组,B=B1B2B3B4B5B6B7B8
*/
public
static
int
[] press(
int
[] source) {
int
[] ret =
new
int
[
32
];
int
[][] temp =
new
int
[
8
][
6
];
int
[][][] s = { s1, s2, s3, s4, s5, s6, s7, s8 };
StringBuffer str =
new
StringBuffer();
for
(
int
i =
0
; i <
8
; i++) {
for
(
int
j =
0
; j <
6
; j++) {
temp[i][j] = source[i *
6
+ j];
}
}
for
(
int
i =
0
; i <
8
; i++) {
// (16)
int
x = temp[i][
0
] *
2
+ temp[i][
5
];
// (2345)
int
y = temp[i][
1
] *
8
+ temp[i][
2
] *
4
+ temp[i][
3
] *
2
+ temp[i][
4
];
int
val = s[i][x][y];
String ch = int2Hex(val);
// System.out.println("x=" + x + ",y=" + y + "-->" + ch);
// String ch = Integer.toBinaryString(val);
str.append(ch);
}
// System.out.println(str.toString());
ret = string2Binary(str.toString());
// printArr(ret);
// 置换P
ret = dataP(ret);
return
ret;
}
/**
*
* 置换P(32bit)
*
* @param source
*
* @return
*/
public
static
int
[] dataP(
int
[] source) {
int
[] dest =
new
int
[
32
];
int
[] temp = {
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
};
int
len = source.length;
for
(
int
i =
0
; i < len; i++) {
dest[i] = source[temp[i] -
1
];
}
return
dest;
}
/**
*
* @param R
* (�?2bit)
*
* @param K
* (48bit的轮子密�?
*
* @return 32bit
*/
public
static
int
[] f(
int
[] R,
int
[] K) {
int
[] dest =
new
int
[
32
];
int
[] temp =
new
int
[
48
];
// 先将输入32bit扩展�?8bit
int
[] expendR = expend(R);
// 48bit
// 与轮子密钥进行异或运�?
temp = diffOr(expendR, K);
// 压缩�?2bit
dest = press(temp);
// System.out.println("need press data----->");
// printArr(temp);
return
dest;
}
/**
*
* 两个等长的数组做异或
*
* @param source1
*
* @param source2
*
* @return
*/
public
static
int
[] diffOr(
int
[] source1,
int
[] source2) {
int
len = source1.length;
int
[] dest =
new
int
[len];
for
(
int
i =
0
; i < len; i++) {
dest[i] = source1[i] ^ source2[i];
}
return
dest;
}
/**
*
* DES加密--->对称密钥
*
* D = Ln(32bit)+Rn(32bit)
*
* 经过16轮置�?
*
* @param D
* (16byte)明文
*
* @param K
* (16byte)轮子密钥
*
* @return (16byte)密文
*/
public
static
String encryption(String D, String K) {
String str =
""
;
int
[] temp =
new
int
[
64
];
int
[] data = string2Binary(D);
// printArr(data);
// 第一步初始置�?
data = changeIP(data);
// printArr(data);
int
[][] left =
new
int
[
17
][
32
];
int
[][] right =
new
int
[
17
][
32
];
for
(
int
j =
0
; j <
32
; j++) {
left[
0
][j] = data[j];
right[
0
][j] = data[j +
32
];
}
// printArr(left[0]);
// printArr(right[0]);
setKey(K);
// sub key ok
for
(
int
i =
1
; i <
17
; i++) {
// 获取(48bit)的轮子密�?
int
[] key = subKey[i -
1
];
// L1 = R0
left[i] = right[i -
1
];
// R1 = L0 ^ f(R0,K1)
int
[] fTemp = f(right[i -
1
], key);
// 32bit
right[i] = diffOr(left[i -
1
], fTemp);
}
// �?��组合的时候,左右调换**************************************************
for
(
int
i =
0
; i <
32
; i++) {
temp[i] = right[
16
][i];
temp[
32
+ i] = left[
16
][i];
}
temp = changeInverseIP(temp);
str = binary2ASC(intArr2Str(temp));
return
str;
}
/**
*
* DES解密--->对称密钥
*
* 解密算法与加密算法基本相同,不同之处仅在于轮子密钥的使用顺序逆序,即解密的第1
*
* 轮子密钥为加密的�?6 轮子密钥,解密的�? 轮子密钥为加密的�?5 轮子密钥,�?…,
*
* 解密的第16 轮子密钥为加密的�? 轮子密钥�?
*
* @param source密文
*
* @param key密钥
*
* @return
*/
public
static
String discryption(String source, String key) {
String str =
""
;
int
[] data = string2Binary(source);
// 64bit
// 第一步初始置�?
data = changeIP(data);
int
[] left =
new
int
[
32
];
int
[] right =
new
int
[
32
];
int
[] tmp =
new
int
[
32
];
for
(
int
j =
0
; j <
32
; j++) {
left[j] = data[j];
right[j] = data[j +
32
];
}
setKey(key);
// sub key ok
for
(
int
i =
16
; i >
0
; i--) {
// 获取(48bit)的轮子密�?
/********* 不同之处 **********/
int
[] sKey = subKey[i -
1
];
tmp = left;
// R1 = L0
left = right;
// L1 = R0 ^ f(L0,K1)
int
[] fTemp = f(right, sKey);
// 32bit
right = diffOr(tmp, fTemp);
}
// �?��组合的时候,左右调换**************************************************
for
(
int
i =
0
; i <
32
; i++) {
data[i] = right[i];
data[
32
+ i] = left[i];
}
data = changeInverseIP(data);
for
(
int
i =
0
; i < data.length; i++) {
str += data[i];
}
str = binary2ASC(str);
return
str;
}
/**
*
* 单�?长密钥DES(16byte)
*
* @param source
*
* @param key
*
* @param type
* 0:encrypt 1:discrypt
*
* @return
*/
public
static
String DES_1(String source, String key,
int
type) {
if
(source.length() !=
16
|| key.length() !=
16
)
return
null
;
if
(type ==
0
) {
return
encryption(source, key);
}
if
(type ==
1
) {
return
discryption(source, key);
}
return
null
;
}
/**
*
*
*
* @param source
*
* @param key
*
* @param type
* 0:encrypt 1:discrypt
*
* @return
*/
public
static
String DES_2(String source, String key,
int
type) {
return
null
;
}
/**
*
* 三重DES算法(双�?长密�?32byte))
*
* 密钥K1和K2
*
* 1、先用K1加密明文
*
* 2、接�?��K2对上�?��的结果进行解�?
*
* 3、然后用K1对上�?��的结果进行加�?
*
* @param source
*
* @param key
*
* @param type
* 0:encrypt 1:discrypt
*
* @return
*/
public
static
String DES_3_new(String source, String key,
int
type) {
String temp =
""
;
for
(
int
i =
0
;i<source.length()/
16
;i++){
String str = source.substring(i*
16
,(i+
1
)*
16
);
temp+=DES_3(str,key,type);
}
return
temp;
}
public
static
String DES_3(String source, String key,
int
type) {
if
(key.length() !=
32
|| source.length() !=
16
)
return
null
;
String temp =
null
;
String K1 = key.substring(
0
, key.length() /
2
);
String K2 = key.substring(key.length() /
2
);
// System.out.println("K1--->" + K1);
//
// System.out.println("K2--->" + K2);
if
(type ==
0
) {
temp = encryption(source, K1);
// System.out.println("step1--->" + temp);
temp = discryption(temp, K2);
// System.out.println("step2--->" + temp);
return
encryption(temp, K1);
}
if
(type ==
1
) {
temp = discryption(source, K1);
temp = encryption(temp, K2);
return
discryption(temp, K1);
}
return
null
;
}
/************************************ 48bit的轮子密钥的生成 **********************************************************/
/**
*
* �?4bit的密钥转换成56bit
*
* @param source
*
* @return
*/
public
static
int
[] keyPC_1(
int
[] source) {
int
[] dest =
new
int
[
56
];
int
[] temp = {
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
};
for
(
int
i =
0
; i <
56
; i++) {
dest[i] = source[temp[i] -
1
];
}
return
dest;
}
/**
*
* 将密钥循环左移i�?
*
* @param source
* 二进制密钥数�?
*
* @param i
* 循环左移位数
*
* @return
*/
public
static
int
[] keyLeftMove(
int
[] source,
int
i) {
int
temp =
0
;
int
len = source.length;
int
ls = LS[i];
// System.out.println("len" + len + ",LS[" + i + "]=" + ls);
for
(
int
k =
0
; k < ls; k++) {
temp = source[
0
];
for
(
int
j =
0
; j < len -
1
; j++) {
source[j] = source[j +
1
];
}
source[len -
1
] = temp;
}
return
source;
}
/**
*
* �?6bit的密钥转换成48bit
*
* @param source
*
* @return
*/
public
static
int
[] keyPC_2(
int
[] source) {
int
[] dest =
new
int
[
48
];
int
[] temp = {
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
};
for
(
int
i =
0
; i <
48
; i++) {
dest[i] = source[temp[i] -
1
];
}
return
dest;
}
/**
*
* 获取轮子密钥(48bit)
*
* @param source
*
* @return
*/
public
static
void
setKey(String source) {
if
(subKey.length >
0
)
subKey =
new
int
[
16
][
48
];
// 装换�?4bit
int
[] temp = string2Binary(source);
// �?6bit均分成两部分
int
[] left =
new
int
[
28
];
int
[] right =
new
int
[
28
];
// 经过PC-1�?4bit转换�?6bit
int
[] temp1 =
new
int
[
56
];
temp1 = keyPC_1(temp);
// printArr(temp1);
// 将经过转换的temp1均分成两部分
for
(
int
i =
0
; i <
28
; i++) {
left[i] = temp1[i];
right[i] = temp1[i +
28
];
}
// 经过16次循环左移,然后PC-2置换
for
(
int
i =
0
; i <
16
; i++) {
left = keyLeftMove(left, LS[i]);
right = keyLeftMove(right, LS[i]);
for
(
int
j =
0
; j <
28
; j++) {
temp1[j] = left[j];
temp1[j +
28
] = right[j];
}
// printArr(temp1);
subKey[i] = keyPC_2(temp1);
}
}
public
static
void
printArr(
int
[] source) {
int
len = source.length;
for
(
int
i =
0
; i < len; i++) {
System.out.print(source[i]);
}
System.out.println();
}
/**
*
* 将ASC字符串转�?6进制字符�?
*
* @param asc
*
* @return
*/
public
static
String ASC_2_HEX(String asc) {
StringBuffer hex =
new
StringBuffer();
try
{
byte
[] bs = asc.toUpperCase().getBytes(
"UTF-8"
);
for
(
byte
b : bs) {
hex.append(Integer.toHexString(
new
Byte(b).intValue()));
}
}
catch
(UnsupportedEncodingException e) {
e.printStackTrace();
}
return
hex.toString();
}
/**
*
* �?6进制的字符串转换成ASC的字符串
*
* �?6进制的字符串压缩成BCD�?30313233343536373839414243444546)-->(0123456789ABCDEF)
*
* @param hex
*
* @return
*/
public
static
String HEX_2_ASC(String hex) {
String asc =
null
;
int
len = hex.length();
byte
[] bs =
new
byte
[len /
2
];
for
(
int
i =
0
; i < len /
2
; i++) {
bs[i] = Byte.parseByte(hex.substring(i *
2
, i *
2
+
2
),
16
);
}
try
{
asc =
new
String(bs,
"UTF-8"
);
}
catch
(UnsupportedEncodingException e) {
e.printStackTrace();
}
return
asc;
}
/**
*
* 计算MAC(hex)
*
* ANSI-X9.9-MAC(16的整数�?不补)
*
* PBOC-DES-MAC(16的整数�?�?000000000000000)
*
* 使用单�?长密钥DES算法
*
* @param key密钥
* (16byte)
*
* @param vector初始向量0000000000000000
*
* @param data数据
*
* @return mac
*/
public
static
String MAC(String key, String vector, String data,
int
type) {
if
(type == ASC) {
data = ASC_2_HEX(data);
}
int
len = data.length();
int
arrLen = len /
16
+
1
;
String[] D =
new
String[arrLen];
if
(vector ==
null
)
vector =
"0000000000000000"
;
if
(len %
16
==
0
) {
data +=
"8000000000000000"
;
}
else
{
data +=
"80"
;
for
(
int
i =
0
; i <
15
- len %
16
; i++) {
data +=
"00"
;
}
}
for
(
int
i =
0
; i < arrLen; i++) {
D[i] = data.substring(i *
16
, i *
16
+
16
);
System.out.println(
"D["
+ i +
"]="
+ D[i]);
}
// D0 Xor Vector
String I = xOr(D[
0
], vector);
String O =
null
;
for
(
int
i =
1
; i < arrLen; i++) {
// System.out.println(i + "**************");
// System.out.println("I=" + I);
O = DES_1(I, key,
0
);
// System.out.println("O=" + O);
I = xOr(D[i], O);
// System.out.println("I=" + I);
}
I = DES_1(I, key,
0
);
return
I;
}
/**
*
* 将s1和s2做异或,然后返回
*
* @param s1
*
* @param s2
*
* @return
*/
public
static
String xOr(String s1, String s2) {
int
[] iArr = diffOr(string2Binary(s1), string2Binary(s2));
return
binary2ASC(intArr2Str(iArr));
}
/**
*
* 将int类型数组拼接成字符串
*
* @param arr
*
* @return
*/
public
static
String intArr2Str(
int
[] arr) {
StringBuffer sb =
new
StringBuffer();
for
(
int
i =
0
; i < arr.length; i++) {
sb.append(arr[i]);
}
return
sb.toString();
}
/**
*
* 将data分散
*
* @param data
*
* @param key
*
* @param type
*
* @return
*/
public
static
String divData(String data, String key,
int
type) {
String left =
null
;
String right =
null
;
if
(type == HEX) {
left = key.substring(
0
,
16
);
right = key.substring(
16
,
32
);
}
if
(type == ASC) {
left = ASC_2_HEX(key.substring(
0
,
8
));
right = ASC_2_HEX(key.substring(
8
,
16
));
}
// 加密
data = DES_1(data, left,
0
);
// 解密
data = DES_1(data, right,
1
);
// 加密
data = DES_1(data, left,
0
);
return
data;
}
/**
*
* 取反(10001)--->(01110)
*
* @param source
*
* @return
*/
public
static
String reverse(String source) {
int
[] data = string2Binary(source);
int
j =
0
;
for
(
int
i : data) {
data[j++] =
1
- i;
}
return
binary2ASC(intArr2Str(data));
}
/**
*
* 主密钥需要经过两次分散获得IC卡中的子密钥
*
* @param issuerFlag发卡方标识符
*
* @param appNo应用序列号即卡号
*
* @param mpk主密钥
*
* @return
*/
public
static
String getDPK(String issuerFlag, String appNo, String mpk) {
// 第一次分散
StringBuffer issuerMPK =
new
StringBuffer();
// 获取Issuer MPK左半边
issuerMPK.append(divData(issuerFlag, mpk,
0
));
// 获取Issuer MPK右半边
issuerMPK.append(divData(reverse(issuerFlag), mpk,
0
));
// 第二次分散
StringBuffer dpk =
new
StringBuffer();
// 获取DPK左半边
dpk.append(divData(appNo, issuerMPK.toString(),
0
));
// 获取DPK右半边
dpk.append(divData(reverse(appNo), issuerMPK.toString(),
0
));
return
dpk.toString();
}
/**
*
* 三重DES算法(双�?长密�?32byte))
*
* 密钥K1和K2
*
* 1、先用K1加密明文
*
* 2、接�?��K2对上�?��的结果进行解�?
*
* 3、然后用K1对上�?��的结果进行加�?
*
* @param source
*
* @param key
*
* @param type
* 0:encrypt 1:discrypt
*
* @return
*/
public
static
String DEDES_3(String source, String key,
int
type) {
if
(key.length() !=
32
|| source.length() !=
16
)
return
null
;
String temp =
null
;
String K1 = key.substring(
0
, key.length() /
2
);
String K2 = key.substring(key.length() /
2
);
// System.out.println("K1--->" + K1);
// System.out.println("K2--->" + K2);
if
(type ==
0
) {
temp = encryption(source, K1);
// System.out.println("step1--->" + temp);
temp = discryption(temp, K2);
// System.out.println("step2--->" + temp);
return
encryption(temp, K1);
}
if
(type ==
1
) {
temp = discryption(source, K1);
temp = encryption(temp, K2);
return
discryption(temp, K1);
}
return
null
;
}
public
static
void
main(String[] args)
throws
Exception {
//B2E8F2E11778F601
//7576242348C58915
System.out.println(DES_1(
"3630ADF459CB24DA"
,
"87077F2FD88BD8B8"
,
0
));
System.out.println(DES_1(
"3630ADF459CB24DA"
,
"87077F2FD88BD8B87576242348C58915"
,
1
));
}
}