深入WEP密码破解原理
生活随笔
收集整理的這篇文章主要介紹了
深入WEP密码破解原理
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
首先看看WEP
加密
,解密的流程圖
WEP加密算法實際上是利用RC4流密碼算法作為偽隨機數產生器,將由初始矢量IV和WEP密鑰組合而成的種子生成WEP密鑰流(圖中的KSA和PRGA部分),再由該密鑰流與WEP幀數據負載進行異或運算來完成加密運算.
RC4流密碼是面向字節的,在算法過程中只是用了置換的方法,按照圖中分成的兩個部分,其C代碼如下
KSA部分:
[cpp] view plaincopy
int i,j = 0;
for (i = 0; i < 256; i++)
{
s[i] = i;
}
for (i = 0; i < 256; i++)
{
k[i] = key[i % 8];//針對64bit的WEP加密,128bit的為[i % 16]
}
for (i = 0; i < 256; i++)
{
j = (j + s[i] + k[i]) % 256;
Swap(s[i], s[j]);//進行置換
}
其中s[256]為狀態列,k[256]為密鑰列,key[8]為64位的密鑰,狀態列初始化為{0,1,2,3, , ,255},密鑰列按照提供的密鑰8字節重復填充至256字節滿,通過置換,生成了一個狀態列用以生成密鑰流.
PRGA部分(只生成256個字節的密鑰流):
[cpp] view plaincopy
for (i = 0, j = 0, LengthofKeyStream = 0; LengthofKeyStream < 256; LengthofKeyStream++)
{
i = (i + 1) % 256;
j = (j + s[i]) % 256;
Swap(s[i], s[j]);
keystream[LengthofKeyStream] = s[(s[i] + s[j]) % 256];
}
至此,我們就有了一個可以進行異或加密的密鑰流keystream[256].在WEP加密當中應該是根據數據data的長度來調整需要得到的密鑰流的長度,這里做了簡單的處理.
在對使用WEP加密的無線網絡抓包的時候,由于ARP包和IP包明文的第一字節是802.2頭標(0xAA),這樣我們就有了數據第一字節的明文(0xAA),同時我們也有了密文的第一字節,當將這兩個字節進行異或的時候,我們可以得到keystream[0],也就是偽隨機生成序列的第一字節,現在通過對這第一個字節進行分析,看看能否逆推出某個密鑰字節.
根據PRGA部分代碼,執行第一次循環時生成keystream[0],初始條件i=0,j=0,按流程走下來,最后可知keystream[0]=s[s[1]+s[s[1]]],假設s[1]的值為X,s[s[1]](即s[X])的值為Y, s[s[1]+s[s[1]]](即s[X+Y])的值為Z,則如圖
由此可以看出,keystream[0]的值受3個值的影響,分別是X,Y,和Z.這3個值是在KSA算法當中通過置換形成的.
[cpp] view plaincopy
for (i = 0; i < 256; i++)
{
j = (j + s[i] + k[i]) % 256;
Swap(s[i], s[j]);//進行置換
}
注意到,當生成供給PRGA使用的狀態列的時候,進行的KSA循環是256次,根據大量的數據統計表明[1],在經過i(i>=1)次KSA循環之后,X,Y,Z三者不參與接下來置換的概率大概是0.05大一點,也就是100次里面大概有5次,X,Y,Z再之后的循環當中是保持不變的,一直保持在這個位置沒有被置換,這樣最后利用這個狀態列生成的keystream[0]的值就是Z,這種狀態稱為斷然狀態(Resolved Condition),如果用一個處于斷然狀態的密鑰流進行異或加密,我們就能夠從中得到與密鑰相關的一些信息,利用已知的密鑰流第一個字節keystream[0]推算出密鑰當中的一個字節.
舉例來說,現在現實的情況是這樣的.我們知道的初始向量IV為3個字節,即密鑰的結構為key[8]={IV[0], IV[1], IV[2], USER[0], USER[1], USER[2], USER[3], USER[4]},USER[]表示用戶自己定義的5個字節密鑰.加上IV的3個字節就是8個字節64bit,回過頭看KSA算法中的置換循環:
[cpp] view plaincopy
for (i = 0; i < 256; i++)
{
j = (j + s[i] + k[i]) % 256;
Swap(s[i], s[j]);//進行置換
}
由于i從0開始,j的值與s[i]的值和k[i]的值相關,s[i]的初始值我們知道,s[i]=i,那么現在知道了key[0],key[1],key[2]這3個值,我們就可以計算得到3個狀態列(即經過3次循環時s[]的值),我們用s_n[](如s_1[])表示i=n時進行置換后的狀態列,用j_n(如j_1)表示i=n時j的值,也就是說,我們可以根據已知的條件推算出s_0[],s_1[],s_2[],j_0,j_1,j_2,假設在i=3時,狀態列進入斷然狀態,那么根據前面的分析,此時有keystream[0]=s_3[s_3[1]+s_3[s_3[1]]],若此IV滿足下面兩個條件:1.s_3[1]<3;2.s_3[1]+s_3[s_3[1]]=3.此時就有keystream[0]=s_3[3],由于s_3[3]是由s_2[j_3]置換而來的(Swap(s[i], s[j]);)[2],j_3=j_2+s_2[3]+k[3],k[3]也就是key[3],則k[3]=j_3-j_2-s_2[3],根據等式,j_3通過在s_2[]中查找keystream[0]的值得到其索引即是j_3,j_2可以通過計算得到,s_2[3]已知,這樣就可以計算出k[3]的值,有一定的概率是正確的,對于k[4]的取得方式也是以此類推,建立在計算出的k[3]值的基礎上.
考慮現在具有特殊形式的的IV={3, 255, N},N表示任意數,用一個表格表示s狀態列在i各個值時候的情況:
初始狀態i=0,j=0
S初始
0
1
2
3
…
5+N
…
255
i=0,j_0=3
s_0
3
1
2
0
…
5+N
…
255
i=1,j_1=3
s_1
3
0
2
1
…
5+N
…
255
i=2,j_2=5+N
s_2
3
0
5+N
1
…
2
…
255
i=3,j_3=6+N+k[3]
s_3
3
0
5+N
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
由上表可以得知,s_3[3]=s_2[6+N+k[3]]=s_2[5+N+1+K[3]]=s_2[j_2+s_2[3]+k[3]],由此可以求出k[3]的值.特殊形式IV只要滿足那兩個條件即可,不一定是給出的{3, 255, N}的形式.
WEP加密算法實際上是利用RC4流密碼算法作為偽隨機數產生器,將由初始矢量IV和WEP密鑰組合而成的種子生成WEP密鑰流(圖中的KSA和PRGA部分),再由該密鑰流與WEP幀數據負載進行異或運算來完成加密運算.
RC4流密碼是面向字節的,在算法過程中只是用了置換的方法,按照圖中分成的兩個部分,其C代碼如下
KSA部分:
[cpp] view plaincopy
int i,j = 0;
for (i = 0; i < 256; i++)
{
s[i] = i;
}
for (i = 0; i < 256; i++)
{
k[i] = key[i % 8];//針對64bit的WEP加密,128bit的為[i % 16]
}
for (i = 0; i < 256; i++)
{
j = (j + s[i] + k[i]) % 256;
Swap(s[i], s[j]);//進行置換
}
其中s[256]為狀態列,k[256]為密鑰列,key[8]為64位的密鑰,狀態列初始化為{0,1,2,3, , ,255},密鑰列按照提供的密鑰8字節重復填充至256字節滿,通過置換,生成了一個狀態列用以生成密鑰流.
PRGA部分(只生成256個字節的密鑰流):
[cpp] view plaincopy
for (i = 0, j = 0, LengthofKeyStream = 0; LengthofKeyStream < 256; LengthofKeyStream++)
{
i = (i + 1) % 256;
j = (j + s[i]) % 256;
Swap(s[i], s[j]);
keystream[LengthofKeyStream] = s[(s[i] + s[j]) % 256];
}
至此,我們就有了一個可以進行異或加密的密鑰流keystream[256].在WEP加密當中應該是根據數據data的長度來調整需要得到的密鑰流的長度,這里做了簡單的處理.
在對使用WEP加密的無線網絡抓包的時候,由于ARP包和IP包明文的第一字節是802.2頭標(0xAA),這樣我們就有了數據第一字節的明文(0xAA),同時我們也有了密文的第一字節,當將這兩個字節進行異或的時候,我們可以得到keystream[0],也就是偽隨機生成序列的第一字節,現在通過對這第一個字節進行分析,看看能否逆推出某個密鑰字節.
根據PRGA部分代碼,執行第一次循環時生成keystream[0],初始條件i=0,j=0,按流程走下來,最后可知keystream[0]=s[s[1]+s[s[1]]],假設s[1]的值為X,s[s[1]](即s[X])的值為Y, s[s[1]+s[s[1]]](即s[X+Y])的值為Z,則如圖
由此可以看出,keystream[0]的值受3個值的影響,分別是X,Y,和Z.這3個值是在KSA算法當中通過置換形成的.
[cpp] view plaincopy
for (i = 0; i < 256; i++)
{
j = (j + s[i] + k[i]) % 256;
Swap(s[i], s[j]);//進行置換
}
注意到,當生成供給PRGA使用的狀態列的時候,進行的KSA循環是256次,根據大量的數據統計表明[1],在經過i(i>=1)次KSA循環之后,X,Y,Z三者不參與接下來置換的概率大概是0.05大一點,也就是100次里面大概有5次,X,Y,Z再之后的循環當中是保持不變的,一直保持在這個位置沒有被置換,這樣最后利用這個狀態列生成的keystream[0]的值就是Z,這種狀態稱為斷然狀態(Resolved Condition),如果用一個處于斷然狀態的密鑰流進行異或加密,我們就能夠從中得到與密鑰相關的一些信息,利用已知的密鑰流第一個字節keystream[0]推算出密鑰當中的一個字節.
舉例來說,現在現實的情況是這樣的.我們知道的初始向量IV為3個字節,即密鑰的結構為key[8]={IV[0], IV[1], IV[2], USER[0], USER[1], USER[2], USER[3], USER[4]},USER[]表示用戶自己定義的5個字節密鑰.加上IV的3個字節就是8個字節64bit,回過頭看KSA算法中的置換循環:
[cpp] view plaincopy
for (i = 0; i < 256; i++)
{
j = (j + s[i] + k[i]) % 256;
Swap(s[i], s[j]);//進行置換
}
由于i從0開始,j的值與s[i]的值和k[i]的值相關,s[i]的初始值我們知道,s[i]=i,那么現在知道了key[0],key[1],key[2]這3個值,我們就可以計算得到3個狀態列(即經過3次循環時s[]的值),我們用s_n[](如s_1[])表示i=n時進行置換后的狀態列,用j_n(如j_1)表示i=n時j的值,也就是說,我們可以根據已知的條件推算出s_0[],s_1[],s_2[],j_0,j_1,j_2,假設在i=3時,狀態列進入斷然狀態,那么根據前面的分析,此時有keystream[0]=s_3[s_3[1]+s_3[s_3[1]]],若此IV滿足下面兩個條件:1.s_3[1]<3;2.s_3[1]+s_3[s_3[1]]=3.此時就有keystream[0]=s_3[3],由于s_3[3]是由s_2[j_3]置換而來的(Swap(s[i], s[j]);)[2],j_3=j_2+s_2[3]+k[3],k[3]也就是key[3],則k[3]=j_3-j_2-s_2[3],根據等式,j_3通過在s_2[]中查找keystream[0]的值得到其索引即是j_3,j_2可以通過計算得到,s_2[3]已知,這樣就可以計算出k[3]的值,有一定的概率是正確的,對于k[4]的取得方式也是以此類推,建立在計算出的k[3]值的基礎上.
考慮現在具有特殊形式的的IV={3, 255, N},N表示任意數,用一個表格表示s狀態列在i各個值時候的情況:
初始狀態i=0,j=0
S初始
0
1
2
3
…
5+N
…
255
i=0,j_0=3
s_0
3
1
2
0
…
5+N
…
255
i=1,j_1=3
s_1
3
0
2
1
…
5+N
…
255
i=2,j_2=5+N
s_2
3
0
5+N
1
…
2
…
255
i=3,j_3=6+N+k[3]
s_3
3
0
5+N
…
…
…
…
…
…
…
…
…
…
…
…
…
…
…
由上表可以得知,s_3[3]=s_2[6+N+k[3]]=s_2[5+N+1+K[3]]=s_2[j_2+s_2[3]+k[3]],由此可以求出k[3]的值.特殊形式IV只要滿足那兩個條件即可,不一定是給出的{3, 255, N}的形式.
求出了k[3]之后可以進一步的求的k[4],以此類推直到求得k[7],由于狀態列進入斷然狀態存在一定概率,因此通過大量的數據包進行推算,然后根據得到的推算密鑰字節進行統計,選取出現概率高的推算密鑰字節進行組合,之后再進行驗證即可得到WEP的密鑰.
轉載于:http://www.2cto.com/kf/201204/126344.html
總結
以上是生活随笔為你收集整理的深入WEP密码破解原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: google 企业邮箱 smtp pop
- 下一篇: EasyBoot教程三:制作GHOST多