最近忙,事比較多,活多了,還要降薪,唉。沒什麼時間看書,將以前的一些技術blog也移到這裡。NTLM在去年年底和今年年初研究過一陣子,寫了總結和
例子程式。裡面涉及很多演算法,在網上查了很久。(下面是以前的部落格)最近想實現一個通過PROXY穿越的網路編程,將相關的內容進行一下匯總。很多東西來
自網路共產主義,也應該為共產主義有所回饋。介紹DES演算法之二的實現。
步驟二:16次計算(16 interations)
在步驟一中,我們擷取了64bits的s,以及56bits的key。s分為2個32bit的序列,分布成為L和R,根據第一步計算,我們有了L0、R0,以及K0,進行如下的操作:L1=R0
R1=L0 XOR F(R0,K1)
我們得到了新的L1和R1,重複操作,直至得到L16和R16,操作公式為:Li = R i-1
Ri = L i-1 XOR F(Ri-1,Ki)
A:Ki的擷取
在這個過程中,我們每次運算的操作需要得到新的ki進行參與。下面將介紹如何從K0依次16個擷取Ki(K1-K16)。K0是一個56bits的資料,我們將其存貯56個位元組的key數組中。這56個位元均分為2組,第一組0-27,第二組28-55。
左移位移量:
1, 1, 2, 2, 2, 2, 2, 2, 1, 2,
2, 2, 2, 2, 2, 1
對於Ki,從左移位移量選擇對應的位移量,例如K1=1,K4=2。將兩組28位的位元分別左移指定的便宜量。例如對於K1,經過左移後,第一組為
1-27,0,第二組為29-55,28。得到一個新的56位元的資料,請保留這個新的序列,記做K1',這個資料根據下面進行序列重排:
|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|
經過重新排序後,我們得到48位元的資料,這個就是K1。由此我們獲得了第一個參與運算的K1。
對於Ki,將Ki-1',例如計算K2,將上次我們得到的K1',分為兩組,進行相應的左移操作,得到Ki’,例如計算K2是,我們將K1’分為兩組,每組左移1為,得到K2’,將Ki’進行同樣排序,得到Ki。
通過這樣的操作,我們依次得到16個Ki,代碼如下:
static int key_offset[] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2,
2, 2, 2, 1};
static int ip_key[] ={
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 void getkey(IN OUT unsigned char * key,int offset){
unsigned
char temp[28];
memcpy(temp,key + offset,28-offset);
memcpy(temp
+ 28 - offset, key , offset);
memcpy(key,temp,28);
memcpy(temp,key + 28 + offset,28-offset);
memcpy(temp
+ 28 - offset, key + 28 , offset);
memcpy(key +
28,temp,28);
}
void algorithm_des(IN unsigned char * src, IN unsigned char *
secrect,
OUT unsigned char * dst){
......
//步驟二:
//擷取原始的L0和R0
memcpy(L,s,32);
memcpy(R,s+32,32);
//進行16次計算
for(i = 0; i
< 16 ; i++){
//擷取Ki'仍然放置在key中
getkey(key,key_offset[i]);
//擷取Ki,放置在K中
initail_permutation(key,ip_key,48,K);
}
}
B:F計算
我們已經有R0,對於每次計算Ri,都將有Ri-1,根據A的步驟,我們已經有了K1,對於每次計算,我們也有Ki。在這個步驟中,我們將實現F(Ri-1,Ki)。
step B.1:
對於Ri-1進行序列交換,產生一個48位元的資料,排序方式如下:
| 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 |
這組48位元的資料和Ki進行異或(XOR),得到一組新的48bite的資料,我們暫時記做E.
step B.2: S
box的運算
48位元的資料均分為8份,每份6位元,我們分別根據S-box的變換,每份產生4位元的資料,產生一個32bite的資料。
1、從6位元的資料中擷取一個行號m和一個列號n。
m=b0b5,n=b1b2b3b4
例如6位元的資料為100101,則m=11(3),n=0010(2)
2、根據行號和列號,在S-box的序列中,查到相應的數值。48位元分為8組,每組查詢的S-box是不一樣的,分別為S1, S2,
S3, S4, S5, S6, S7,S8具體如下:
S1: 0列 1列 2列 3列 4列 5列 6列 7列 8列
9列 A列 B列 C列 D列 E列 F列
0行 14
4 13
1
2 15
11 8
3 10
6 12
5
9
0 7
1行 0
15 7
4 14
2 13 1
10 6
12 11 9 5
3 8
2行
4 1
14 8
13 6 2
11 15 12 9
7 3
10 5 0
3行 15
12 8
2 4 9
1 7
5 11 3
14 10
0 6 13
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
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
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,
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
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
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
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
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
我們仍以100101為例子,假設它的第一組6位元,得到m=3,n=2,我們查詢S1,在第3行,第2列中查得8,將其翻譯為二進位,則轉換為4位元
的資料1000,這樣我們得到了新的第一組4位元,如此類推,我們得到了8組4位元的資料,按順序組合成一個32位元的資料,暫時記為E'。
stepB.3:更換順序
將32位元的E’根據下面進行序列更換,得到新的32位元據。
|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|
至此我們完成了F運算。
C:獲得新的Ri和Li
這步驟比較簡單,如下
Li = R i-1
Ri = L i-1 XOR F(Ri-1,Ki)
D:重複16次計算,得到L16和R16
static int ip_e[] = {
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 int ip_p[] = {
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 unsigned char s1[64] = {
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 };
static unsigned char s2[64] = {
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 };
static unsigned char s3[64] = {
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 };
static unsigned char s4[64] = {
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 };
static unsigned char s5[64] = {
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 };
static unsigned char s6[64] = {
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 };
static unsigned char s7[64] = {
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 };
static unsigned char s8[64] = {
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 };
static void s_box_function(IN unsigned char * data,IN unsigned char
* sbox,
OUT unsigned char * dst){
int m =
data[0] * 2 + data[5];
int n =
data[1] * 8 + data[2] * 4 + data[3] * 2 + data[4];
unsigned
char c = sbox[m* 16 + n];
if(c
>= 8){
dst[0] =
1;
c =
c-8;
}else{
dst[0] =
0;
}
if(c
>= 4){
dst[1] =
1;
c =
c-4;
}else{
dst[1] =
0;
}
if(c
>= 2){
dst[2] =
1;
c =
c-2;
}else{
dst[2] =
0;
}
dst[3] =
c;
}
void algorithm_des(IN unsigned char * src, IN unsigned char *
secrect,
OUT unsigned char * dst){
......
//步驟二:
//擷取原始的L0和R0
memcpy(L,s,32);
memcpy(R,s+32,32);
//進行16次計算
for(i = 0; i
< 16 ; i++){
//擷取Ki
getkey(key,key_offset[i]);
initail_permutation(key,ip_key,48,K);
//F計算
initail_permutation(R,ip_e,48,E);
xorbit(E,K,48,E);
s_box_function(E,s1,E);
s_box_function(E + 6,s2,E + 4);
s_box_function(E + 12,s3,E + 8);
s_box_function(E + 18,s4,E + 12);
s_box_function(E + 24,s5,E + 16);
s_box_function(E + 30,s6,E + 20);
s_box_function(E + 36,s7,E + 24);
s_box_function(E + 42,s8,E + 28);
initail_permutation(E,ip_p,32,E);
//更換序列
xorbit(E,L,32,E);
memcpy(L,R,32);
memcpy(R,E,32);
}
}
相關連結:我的網路通訊相關文章
NTLM的實現:
- 實現PROXY穿越(16):NTLM的PROXY穿越
- 實現PROXY穿越(15):NTLM Session Security
- 實現PROXY穿越(14):NTLM type3 Message
- 實現PROXY穿越(13):NTLM type2 Message
- 實現PROXY穿越(12):NTLM type1 Message
- 實現PROXY穿越(11):NTLMv2 session response
- 實現PROXY穿越(10):NTLMv2 response
- 實現PROXY穿越(9):NTLMv1 response
- 實現PROXY穿越(8):NT-Hash的實現
- 實現PROXY穿越(7):MD4和MD5
- 實現PROXY穿越(6):LM-Hash的實現
- 實現PROXY穿越(5):DES演算法之三
- 實現PROXY穿越(4):DES演算法之二
- 實現PROXY穿越(3):DES演算法之一
- 實現PROXY穿越(2):Base64演算法
- 實現PROXY穿越(1):流程和NTLM演算法