最初是下载了一个写好了的Java版SHA1,代码如下:
来源:
http://blog.csdn.net/zyg158/archive/2007/06/26/1667531.aspx
1
public class SHA1
{
2
private final int[] abcde =
{
3
0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0
4
};
5
// 摘要数据存储数组
6
private int[] digestInt = new int[5];
7
// 计算过程中的临时数据存储数组
8
private int[] tmpData = new int[80];
9
// 计算sha-1摘要
10
private int process_input_bytes(byte[] bytedata)
{
11
// 初试化常量
12
System.arraycopy(abcde, 0, digestInt, 0, abcde.length);
13
// 格式化输入字节数组,补10及长度数据
14
byte[] newbyte = byteArrayFormatData(bytedata);
15
// 获取数据摘要计算的数据单元个数
16
int MCount = newbyte.length / 64;
17
// 循环对每个数据单元进行摘要计算
18
for (int pos = 0; pos < MCount; pos++)
{
19
// 将每个单元的数据转换成16个整型数据,并保存到tmpData的前16个数组元素中
20
for (int j = 0; j < 16; j++)
{
21
tmpData[j] = byteArrayToInt(newbyte, (pos * 64) + (j * 4));
22
}
23
// 摘要计算函数
24
encrypt();
25
}
26
return 20;
27
}
28
// 格式化输入字节数组格式
29
private byte[] byteArrayFormatData(byte[] bytedata)
{
30
// 补0数量
31
int zeros = 0;
32
// 补位后总位数
33
int size = 0;
34
// 原始数据长度
35
int n = bytedata.length;
36
// 模64后的剩余位数
37
int m = n % 64;
38
// 计算添加0的个数以及添加10后的总长度
39
if (m < 56)
{
40
zeros = 55 - m;
41
size = n - m + 64;
42
} else if (m == 56)
{
43
zeros = 63;
44
size = n + 8 + 64;
45
} else
{
46
zeros = 63 - m + 56;
47
size = (n + 64) - m + 64;
48
}
49
// 补位后生成的新数组内容
50
byte[] newbyte = new byte[size];
51
// 复制数组的前面部分
52
System.arraycopy(bytedata, 0, newbyte, 0, n);
53
// 获得数组Append数据元素的位置
54
int l = n;
55
// 补1操作
56
newbyte[l++] = (byte) 0x80;
57
// 补0操作
58
for (int i = 0; i < zeros; i++)
{
59
newbyte[l++] = (byte) 0x00;
60
}
61
// 计算数据长度,补数据长度位共8字节,长整型
62
long N = (long) n * 8;
63
byte h8 = (byte) (N & 0xFF);
64
byte h7 = (byte) ((N >> 8) & 0xFF);
65
byte h6 = (byte) ((N >> 16) & 0xFF);
66
byte h5 = (byte) ((N >> 24) & 0xFF);
67
byte h4 = (byte) ((N >> 32) & 0xFF);
68
byte h3 = (byte) ((N >> 40) & 0xFF);
69
byte h2 = (byte) ((N >> 48) & 0xFF);
70
byte h1 = (byte) (N >> 56);
71
newbyte[l++] = h1;
72
newbyte[l++] = h2;
73
newbyte[l++] = h3;
74
newbyte[l++] = h4;
75
newbyte[l++] = h5;
76
newbyte[l++] = h6;
77
newbyte[l++] = h7;
78
newbyte[l++] = h8;
79
return newbyte;
80
}
81
private int f1(int x, int y, int z)
{
82
return (x & y) | (~x & z);
83
}
84
private int f2(int x, int y, int z)
{
85
return x ^ y ^ z;
86
}
87
private int f3(int x, int y, int z)
{
88
return (x & y) | (x & z) | (y & z);
89
}
90
private int f4(int x, int y)
{
91
return (x << y) | x >>> (32 - y);
92
}
93
// 单元摘要计算函数
94
private void encrypt()
{
95
for (int i = 16; i <= 79; i++)
{
96
tmpData[i] = f4(tmpData[i - 3] ^ tmpData[i - 8] ^ tmpData[i - 14] ^
97
tmpData[i - 16], 1);
98
}
99
int[] tmpabcde = new int[5];
100
for (int i1 = 0; i1 < tmpabcde.length; i1++)
{
101
tmpabcde[i1] = digestInt[i1];
102
}
103
for (int j = 0; j <= 19; j++)
{
104
int tmp = f4(tmpabcde[0], 5) +
105
f1(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +
106
tmpData[j] + 0x5a827999;
107
tmpabcde[4] = tmpabcde[3];
108
tmpabcde[3] = tmpabcde[2];
109
tmpabcde[2] = f4(tmpabcde[1], 30);
110
tmpabcde[1] = tmpabcde[0];
111
tmpabcde[0] = tmp;
112
}
113
for (int k = 20; k <= 39; k++)
{
114
int tmp = f4(tmpabcde[0], 5) +
115
f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +
116
tmpData[k] + 0x6ed9eba1;
117
tmpabcde[4] = tmpabcde[3];
118
tmpabcde[3] = tmpabcde[2];
119
tmpabcde[2] = f4(tmpabcde[1], 30);
120
tmpabcde[1] = tmpabcde[0];
121
tmpabcde[0] = tmp;
122
}
123
for (int l = 40; l <= 59; l++)
{
124
int tmp = f4(tmpabcde[0], 5) +
125
f3(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +
126
tmpData[l] + 0x8f1bbcdc;
127
tmpabcde[4] = tmpabcde[3];
128
tmpabcde[3] = tmpabcde[2];
129
tmpabcde[2] = f4(tmpabcde[1], 30);
130
tmpabcde[1] = tmpabcde[0];
131
tmpabcde[0] = tmp;
132
}
133
for (int m = 60; m <= 79; m++)
{
134
int tmp = f4(tmpabcde[0], 5) +
135
f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +
136
tmpData[m] + 0xca62c1d6;
137
tmpabcde[4] = tmpabcde[3];
138
tmpabcde[3] = tmpabcde[2];
139
tmpabcde[2] = f4(tmpabcde[1], 30);
140
tmpabcde[1] = tmpabcde[0];
141
tmpabcde[0] = tmp;
142
}
143
for (int i2 = 0; i2 < tmpabcde.length; i2++)
{
144
digestInt[i2] = digestInt[i2] + tmpabcde[i2];
145
}
146
for (int n = 0; n < tmpData.length; n++)
{
147
tmpData[n] = 0;
148
}
149
}
150
// 4字节数组转换为整数
151
private int byteArrayToInt(byte[] bytedata, int i)
{
152
return ((bytedata[i] & 0xff) << 24) | ((bytedata[i + 1] & 0xff) << 16) |
153
((bytedata[i + 2] & 0xff) << 8) | (bytedata[i + 3] & 0xff);
154
}
155
// 整数转换为4字节数组
156
private void intToByteArray(int intValue, byte[] byteData, int i)
{
157
byteData[i] = (byte) (intValue >>> 24);
158
byteData[i + 1] = (byte) (intValue >>> 16);
159
byteData[i + 2] = (byte) (intValue >>> 8);
160
byteData[i + 3] = (byte) intValue;
161
}
162
// 将字节转换为十六进制字符串
163
private static String byteToHexString(byte ib)
{
164
char[] Digit =
{
165
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',
166
'D', 'E', 'F'
167
};
168
char[] ob = new char[2];
169
ob[0] = Digit[(ib >>> 4) & 0X0F];
170
ob[1] = Digit[ib & 0X0F];
171
String s = new String(ob);
172
return s;
173
}
174
// 将字节数组转换为十六进制字符串
175
private static String byteArrayToHexString(byte[] bytearray)
{
176
String strDigest = "";
177
for (int i = 0; i < bytearray.length; i++)
{
178
strDigest += byteToHexString(bytearray[i]);
179
}
180
return strDigest;
181
}
182
// 计算sha-1摘要,返回相应的字节数组
183
public byte[] getDigestOfBytes(byte[] byteData)
{
184
process_input_bytes(byteData);
185
byte[] digest = new byte[20];
186
for (int i = 0; i < digestInt.length; i++)
{
187
intToByteArray(digestInt[i], digest, i * 4);
188
}
189
return digest;
190
}
191
// 计算sha-1摘要,返回相应的十六进制字符串
192
public String getDigestOfString(byte[] byteData)
{
193
return byteArrayToHexString(getDigestOfBytes(byteData));
194
}
195
public static void main(String[] args)
{
196
String data = "1";
197
System.out.println(data);
198
String digest = new SHA1().getDigestOfString(data.getBytes());
199
System.out.println(digest);
200
}
201
}
202
在我们的一代令牌开发中,我们通过修改其部分源代码(重写sha1及相应的操作),实现otp在Android平台上的实现。其实我的工作量并不大,只是按要求把代码改了改,写一个SHA1类,加入了三个函数,包含初始化,数据更新,更新输出。以修改源代码中的过耦合现象,即digestInt数据不被随便修改,将其初始化过程实现在初始化函数中。
代码如下:
/**
* SHA1类,主要包含encrypt,init,upData,doFinal函数
* @author Snowolf
*
*/public class SHA1{
private final int[] abcde = {
0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0
};
// 摘要数据存储数组
private int[] digestInt = new int[5];
// 计算过程中的临时数据存储数组
private int[] tmpData = new int[80];
/**
* f1是SHA1算法中的一系列函数中的一个,操作32位字x,y,z并且产生32位字作为输出
* @param x 32位字
* @param y 32位字
* @param z 32位字
* @return 运算结果
*/
private int f1(int x, int y, int z) {
return (x & y) | (~x & z);
}
/**
* f2是SHA1算法中的一系列函数中的一个,操作32位字x,y,z并且产生32位字作为输出
* @param x 32位字
* @param y 32位字
* @param z 32位字
* @return 运算结果
*/
private int f2(int x, int y, int z) {
return x ^ y ^ z;
}
/**
* f3是SHA1算法中的一系列函数中的一个,操作32位字x,y,z并且产生32位字作为输出
* @param x 32位字
* @param y 32位字
* @param z 32位字
* @return 运算结果
*/
private int f3(int x, int y, int z) {
return (x & y) | (x & z) | (y & z);
}
/**
* f4是循环移位函数,将x进行循环移位,移位次数为y
* @param x 要移位的字
* @param y 移位次数
* @return 运算结果
*/
private int f4(int x, int y) {
return (x << y) | x >>> (32 - y);
}
/**
* 单元摘要计算函数,函数运算完成后,最终结果储存在digestInt中
* @param Message_Block 为大小16个字的int型数组,即我们已经格式化完成的,要进行加密运算的数据
* @return void
* @author Snowolf
*/
private void encrypt(int[] Message_Block) {
for(int t = 0; t < 16; t++)
{
tmpData[t] = Message_Block[t];
}
for (int i = 16; i <= 79; i++) {
tmpData[i] = f4(tmpData[i - 3] ^ tmpData[i - 8] ^ tmpData[i - 14] ^
tmpData[i - 16], 1);
}
int[] tmpabcde = new int[5];
for (int i1 = 0; i1 < tmpabcde.length; i1++) {
tmpabcde[i1] = digestInt[i1];
}
for (int j = 0; j <= 19; j++) {
int tmp = f4(tmpabcde[0], 5) +
f1(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +
tmpData[j] + 0x5a827999;
tmpabcde[4] = tmpabcde[3];
tmpabcde[3] = tmpabcde[2];
tmpabcde[2] = f4(tmpabcde[1], 30);
tmpabcde[1] = tmpabcde[0];
tmpabcde[0] = tmp;
}
for (int k = 20; k <= 39; k++) {
int tmp = f4(tmpabcde[0], 5) +
f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +
tmpData[k] + 0x6ed9eba1;
tmpabcde[4] = tmpabcde[3];
tmpabcde[3] = tmpabcde[2];
tmpabcde[2] = f4(tmpabcde[1], 30);
tmpabcde[1] = tmpabcde[0];
tmpabcde[0] = tmp;
}
for (int l = 40; l <= 59; l++) {
int tmp = f4(tmpabcde[0], 5) +
f3(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +
tmpData[l] + 0x8f1bbcdc;
tmpabcde[4] = tmpabcde[3];
tmpabcde[3] = tmpabcde[2];
tmpabcde[2] = f4(tmpabcde[1], 30);
tmpabcde[1] = tmpabcde[0];
tmpabcde[0] = tmp;
}
for (int m = 60; m <= 79; m++) {
int tmp = f4(tmpabcde[0], 5) +
f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +
tmpData[m] + 0xca62c1d6;
tmpabcde[4] = tmpabcde[3];
tmpabcde[3] = tmpabcde[2];
tmpabcde[2] = f4(tmpabcde[1], 30);
tmpabcde[1] = tmpabcde[0];
tmpabcde[0] = tmp;
}
for (int i2 = 0; i2 < tmpabcde.length; i2++) {
digestInt[i2] = digestInt[i2] + tmpabcde[i2];//摘要存储在digestInt
}
for (int n = 0; n < tmpData.length; n++) {
tmpData[n] = 0;
}
}
/**
* 初始化函数,将digestInt值初始化为SHA1算法中的原始初值
*/
public void init(){
System.arraycopy(abcde, 0, digestInt, 0, abcde.length);
}
/** SHA1加密运算,其中updata返回值为void,此时digestInt中的数据为计算结果(摘要)
*为16个字的int型数组,即我们已经格式化完成的数据
* @param Message_Block 为大小16个字的int型数组,即我们已经格式化完成的,要进行加密运算的数据
* @author Snowolf
*/
public void upData(int[] Message_Block){
encrypt(Message_Block);
}
/**
* SHA1加密运算,返回值为int[],即返回计算出来的摘要
* @param Message_Block 为大小16个字的int型数组,即我们已经格式化完成的,要进行加密运算的数据
* @return int[5]摘要
* @author Snowolf
*/
public int[] doFinal(int[] Message_Block){
int[] doFinalInt = new int[5];
encrypt(Message_Block);
System.arraycopy(digestInt, 0, doFinalInt, 0, digestInt.length);
return doFinalInt;
}
}
代码如下:
1
/** *//**
2
* SHA1类,主要包含encrypt,init,upData,doFinal函数
3
* @author Snowolf
4
*
5
*/
6
public class SHA1
{
7
private final int[] abcde =
{
8
0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0
9
};
10
// 摘要数据存储数组
11
private int[] digestInt = new int[5];
12
// 计算过程中的临时数据存储数组
13
14
private int[] tmpData = new int[80];
15
/** *//**
16
* f1是SHA1算法中的一系列函数中的一个,操作32位字x,y,z并且产生32位字作为输出
17
* @param x 32位字
18
* @param y 32位字
19
* @param z 32位字
20
* @return 运算结果
21
*/
22
private int f1(int x, int y, int z)
{
23
return (x & y) | (~x & z);
24
}
25
/** *//**
26
* f2是SHA1算法中的一系列函数中的一个,操作32位字x,y,z并且产生32位字作为输出
27
* @param x 32位字
28
* @param y 32位字
29
* @param z 32位字
30
* @return 运算结果
31
*/
32
private int f2(int x, int y, int z)
{
33
return x ^ y ^ z;
34
}
35
/** *//**
36
* f3是SHA1算法中的一系列函数中的一个,操作32位字x,y,z并且产生32位字作为输出
37
* @param x 32位字
38
* @param y 32位字
39
* @param z 32位字
40
* @return 运算结果
41
*/
42
private int f3(int x, int y, int z)
{
43
return (x & y) | (x & z) | (y & z);
44
}
45
/** *//**
46
* f4是循环移位函数,将x进行循环移位,移位次数为y
47
* @param x 要移位的字
48
* @param y 移位次数
49
* @return 运算结果
50
*/
51
private int f4(int x, int y)
{
52
return (x << y) | x >>> (32 - y);
53
}
54
/** *//**
55
* 单元摘要计算函数,函数运算完成后,最终结果储存在digestInt中
56
* @param Message_Block 为大小16个字的int型数组,即我们已经格式化完成的,要进行加密运算的数据
57
* @return void
58
* @author Snowolf
59
*/
60
private void encrypt(int[] Message_Block)
{
61
for(int t = 0; t < 16; t++)
62
{
63
tmpData[t] = Message_Block[t];
64
}
65
for (int i = 16; i <= 79; i++)
{
66
tmpData[i] = f4(tmpData[i - 3] ^ tmpData[i - 8] ^ tmpData[i - 14] ^
67
tmpData[i - 16], 1);
68
}
69
int[] tmpabcde = new int[5];
70
for (int i1 = 0; i1 < tmpabcde.length; i1++)
{
71
tmpabcde[i1] = digestInt[i1];
72
}
73
for (int j = 0; j <= 19; j++)
{
74
int tmp = f4(tmpabcde[0], 5) +
75
f1(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +
76
tmpData[j] + 0x5a827999;
77
tmpabcde[4] = tmpabcde[3];
78
tmpabcde[3] = tmpabcde[2];
79
tmpabcde[2] = f4(tmpabcde[1], 30);
80
tmpabcde[1] = tmpabcde[0];
81
tmpabcde[0] = tmp;
82
}
83
for (int k = 20; k <= 39; k++)
{
84
int tmp = f4(tmpabcde[0], 5) +
85
f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +
86
tmpData[k] + 0x6ed9eba1;
87
tmpabcde[4] = tmpabcde[3];
88
tmpabcde[3] = tmpabcde[2];
89
tmpabcde[2] = f4(tmpabcde[1], 30);
90
tmpabcde[1] = tmpabcde[0];
91
tmpabcde[0] = tmp;
92
}
93
for (int l = 40; l <= 59; l++)
{
94
int tmp = f4(tmpabcde[0], 5) +
95
f3(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +
96
tmpData[l] + 0x8f1bbcdc;
97
tmpabcde[4] = tmpabcde[3];
98
tmpabcde[3] = tmpabcde[2];
99
tmpabcde[2] = f4(tmpabcde[1], 30);
100
tmpabcde[1] = tmpabcde[0];
101
tmpabcde[0] = tmp;
102
}
103
for (int m = 60; m <= 79; m++)
{
104
int tmp = f4(tmpabcde[0], 5) +
105
f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] +
106
tmpData[m] + 0xca62c1d6;
107
tmpabcde[4] = tmpabcde[3];
108
tmpabcde[3] = tmpabcde[2];
109
tmpabcde[2] = f4(tmpabcde[1], 30);
110
tmpabcde[1] = tmpabcde[0];
111
tmpabcde[0] = tmp;
112
}
113
for (int i2 = 0; i2 < tmpabcde.length; i2++)
{
114
digestInt[i2] = digestInt[i2] + tmpabcde[i2];//摘要存储在digestInt
115
}
116
for (int n = 0; n < tmpData.length; n++)
{
117
tmpData[n] = 0;
118
}
119
}
120
/** *//**
121
* 初始化函数,将digestInt值初始化为SHA1算法中的原始初值
122
*/
123
public void init()
{
124
System.arraycopy(abcde, 0, digestInt, 0, abcde.length);
125
}
126
/** *//** SHA1加密运算,其中updata返回值为void,此时digestInt中的数据为计算结果(摘要)
127
*为16个字的int型数组,即我们已经格式化完成的数据
128
* @param Message_Block 为大小16个字的int型数组,即我们已经格式化完成的,要进行加密运算的数据
129
* @author Snowolf
130
*/
131
public void upData(int[] Message_Block)
{
132
encrypt(Message_Block);
133
}
134
/** *//**
135
* SHA1加密运算,返回值为int[],即返回计算出来的摘要
136
* @param Message_Block 为大小16个字的int型数组,即我们已经格式化完成的,要进行加密运算的数据
137
* @return int[5]摘要
138
* @author Snowolf
139
*/
140
public int[] doFinal(int[] Message_Block)
{
141
int[] doFinalInt = new int[5];
142
encrypt(Message_Block);
143
System.arraycopy(digestInt, 0, doFinalInt, 0, digestInt.length);
144
return doFinalInt;
145
}
146
}
147