侧信道实验实验二 S盒DPA侧信道攻击
---------------------------------------202/12/19 更新---------------------------------------
在輸入時除了密鑰的遍歷范圍因為DES的S盒的“6進4出“機制導致范圍限定在0-63以外,明文在作為S盒輸入的時候也是被限制在每組長度為64。我將明文數(shù)組長度從1000更新為64后的猜測正確率也是100%。
-------------------------------------------起始內容-------------------------------------------
實驗目的
實驗人數(shù)
每組1人
系統(tǒng)環(huán)境
Windows
實驗原理
實驗內容
完成Sboxdpa仿真-student.py程序中的空缺部分
-
補充n、plaintext、keyTrue
-
補充HWfun函數(shù),返回輸入的漢明重量
-
補充主函數(shù),得到輸出相應的漢明重量向量
完成Sboxdpa-student.py文件中的空缺部分,即
-
補充plaintext、power_std
-
補充DPAfun函數(shù),計算漢明差值
-
補充主函數(shù),求正確猜測密鑰
實驗測試2組數(shù)據(jù)
實驗步驟
完善Sboxdpa仿真-student.py程序
補充變量
補充n、plaintext、keyTrue三個變量
n = 9 #數(shù)組長度 plainlist = [41, 35, 62, 4, 33, 44, 22, 46, 18] #明文數(shù)組 keyTrue = 43 #加密所用密鑰完善HWfun函數(shù)
本質上是計算十進制數(shù)轉換成二進制后含1的數(shù)量,則可以采用快速法計算。這種方法運算次數(shù)與輸入n的大小無關,只與n中1的個數(shù)有關。如果n的二進制表示中有k個1,那么這個方法只需要循環(huán)k次即可。其原理是不斷清除n的二進制表示中最右邊的1,同時累加計數(shù)器,直至n為0。
補充代碼如下:
def HWfun(num):# 統(tǒng)計輸入num的漢明重量并返回ans = 0if num == 0:return 0while num > 0:num &= (num - 1)ans += 1return ans為什么n &= (n – 1)能清除最右邊的1呢?因為從二進制的角度講,n相當于在n - 1的最低位加上1。舉個例子,8(1000)= 7(0111)+ 1(0001),所以8 & 7 = (1000)&(0111)= 0(0000),清除了8最右邊的1(其實就是最高位的1,因為8的二進制中只有一個1)。再比如7(0111)= 6(0110)+ 1(0001),所以7 & 6 = (0111)&(0110)= 6(0110),清除了7的二進制表示中最右邊的1(也就是最低位的1)。
完善主函數(shù)
使用表格美化庫完善輸出。
補充代碼如下:
if __name__ == "__main__":# 補充:S盒輸出對應漢明重量列表table = pt.PrettyTable()hw_std = []HWout = sboxout(n, plainlist, keyTrue)for i in range(n):hw_std.append(HWfun(HWout[i]))table.add_column('序號',[i for i in range(1,n+1)])table.add_column('明文-十進制',[index for index in plainlist])table.add_column('S盒輸出-十進制', [index for index in HWout])table.add_column('S盒輸出-漢明重量', [index for index in hw_std])print(table)程序運行結果
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳
完善Sboxdpa-student.py程序
補充變量
我在此程序中采用的plaintlist數(shù)組(明文數(shù)組)是由plainlist = list(np.random.randint(64, size=1000))函數(shù)生成的1000長度的數(shù)組,模擬教材上的運行基數(shù)。同理,power_std數(shù)組(正確密鑰處理得到的漢明重量數(shù)組)同樣長度1000,數(shù)組內的元素展示位置在8.4數(shù)據(jù)統(tǒng)計中,“明文數(shù)組長度為1000”那里。
完善DPAfun函數(shù)
Meanfun函數(shù)我有所改動:
def Meanfun(num):total = 0length = len(num)if length == 0:return 0for i in range(length):total = total + num[i]return total / length函數(shù)思想是取使用猜測密鑰處理的漢明重量數(shù)組的中間值作為劃分使用正確密鑰處理的漢明重量數(shù)組的依據(jù),隨后,函數(shù)返回劃分后集合的差值。
補充代碼如下:
def DPAfun(n, pstd, ptest):# 以2為界,計算不同漢明重量的集合差值L_list = []H_list = []med = median(ptest)for i in range(n):if ptest[i] <= med:L_list.append(pstd[i])else:H_list.append(pstd[i])return Meanfun(H_list) - Meanfun(L_list)完善主函數(shù)
運行邏輯&思路為遍歷所有密鑰——64個,將明文和每個密鑰異或后的結果作為S盒的輸入,得到S盒的輸出(模擬DES處理流程),并求得64個漢明重量數(shù)組,將64個漢明重量數(shù)組帶入DPAfun函數(shù)進行運算,取DPAfun函數(shù)返回值中的最大值對應的密鑰,即為正確密鑰。
因為DES的S盒運算是“6進4出”的,明文和密鑰的異或是在進入S盒前,要滿足6位輸入的需求,所以密鑰遍歷是2的六次方次。
補充代碼如下:
if __name__ == "__main__":# 猜測密鑰keyList = [i for i in range(64)]DPAlist = []n = len(plainlist)for i in range(64):hw_std = []HWout = sboxout(n, plainlist, i) #S盒輸出for i in range(n):hw_std.append(HWfun(HWout[i])) #漢明重量DPAlist.append(DPAfun(n, power_std, hw_std)) #正確密鑰得到的漢明重量數(shù)組被劃分成兩個集合后的集合均值差final_dict = dict(zip(keyList,DPAlist))print("正確密鑰為:",max(final_dict, key=final_dict.get)) #取最大集合均值差對應的密鑰運行結果我放在了總結里,方便進行對比。具體位置在8.4數(shù)據(jù)統(tǒng)計中,其中明文數(shù)組長度為1000測試結果的截圖。
思考問題
對分組密碼算法進行DPA攻擊時的基本原理
DPA攻擊是一種對密碼芯片的泄漏功耗 進行統(tǒng)計分析而恢復密鑰的攻擊方法。DPA攻擊的方法是對大量的曲線樣點進行功耗統(tǒng)計測試 ,即根據(jù) 大量功耗樣本來分析密鑰的值 ,它具有比簡單功耗攻擊更高的強度 。
攻擊分組密碼算法我認為是攻擊算法所用的S盒,因為S盒是離散處理數(shù)據(jù),像行位移和列變換這種都是線性變換,離散處理的結果不容易觀察出規(guī)律性。DPA攻擊,需要先獲取N次密碼運算后得到的明文(非密碼運算結果),密文,產生的功耗;然后定義一個與密鑰密切相關的分割函數(shù)J(密文,k)和能量消耗依賴很強的d,猜測子密鑰k值,并基于采樣時間點,得到兩個功耗曲線子集合(d=0和d=1);對功耗曲線進行計算,計算平均功耗值從而得到差分功耗曲線;觀察差分功耗曲線,若某個位置出現(xiàn)明細那的尖峰,則表示k猜測正確;猜測正確后根據(jù)密碼算法的子密鑰生成算法逆推密鑰。(不同分組密碼的子密鑰生成算法和密鑰位數(shù)不同,逆推時窮舉搜索次數(shù)不同)
總結
猜測正確密鑰思路詳解
因為DES的S盒運算是“6進4出”的,所以輸出的數(shù)值化為二進制后所含1的個數(shù)范圍為0-4。所以猜測密鑰處理得到的64個漢明數(shù)組的中間值無外乎就0,1,2,3,4五種。但是只有正確密鑰處理得到的漢明數(shù)組進行DPAfun函數(shù)處理后得到的差值最大。
為什么集合均值的差值最大就是正確密鑰?
猜測密鑰漢明重量數(shù)組的中間值為2時的分析
2本身作為0-5的中間值,在漢明重量數(shù)組內元素基數(shù)達到一定程度時數(shù)組中間值近乎都是2,我的采用1000長度的明文數(shù)組得到的64個漢明重量數(shù)組的中間值全是2。集合劃分是猜測密鑰漢明重量數(shù)組內元素值小于等于2,正確密鑰漢明重量數(shù)組內的元素就要被劃分到L集合,剩下的劃分到H集合,而影響兩個集合的差值的根本原因是部分元素在兩個集合中的遷移。
舉例進行解析比較方便理解:(ptest數(shù)組的中間值為2)
ptsd = [1,2,3,4,4,3,1,2,3,4,3,4,1,2,1,2,……] #正確密鑰得到的漢明重量數(shù)組 ptest = [1,2,3,4,3,4,2,1,1,1,2,2,3,3,4,4,……] #猜測密鑰得到的漢明重量數(shù)組將數(shù)組劃分成五段,方便觀看。
0 1 2 3 4 | 4 3 0 0 1 2 | 3 4 3 4 3 4 | 0 1 2 0 1 2 | ………… 0 1 2 3 4 | 3 4 1 2 2 1 | 0 0 1 1 2 2 | 3 3 3 4 4 4 | …………中間值為2的劃分規(guī)則上面說過了我就不贅述了。我將中間值為2的所有ptsd兩集合劃分情況進行了遍歷舉例。
第一段,ptest數(shù)組和ptsd數(shù)組每一位的對應值都相同,所以不影響劃分后集合的均值差;
第二段,ptest數(shù)組和ptsd數(shù)組雖然每一位的對應值都不同,但是ptsd數(shù)組劃分后0,1,2都劃分到L集合,3,4都劃分到H集合,對集合的均值差不影響;
第三段,ptest數(shù)組和ptsd數(shù)組每一位的對應值都不同,原本應該劃分到H集合的4個ptsd數(shù)組元素因為對應位置的ptest的值小于等于中間值2,結果被劃分到了L集合,這就導致L集合的平均值必然增大,H集合的平均值可能減小,集合均值差減小;
第四段,ptest數(shù)組和ptsd數(shù)組每一位的對應值都不同,原本應該劃分到L集合的4個ptsd數(shù)組元素因為對應位置的ptest的值大于中間值2,結果被劃分到了H集合,這就導致H集合的平均值必然減小,L集合的平均值可能增大,集合均值差減小;
然后問題又來了,為什么第三、第四段的集合元素劃分會導致兩個集合的“必然”變化和可能變換呢?
集合均值的“必然”和“可能”變化分析
首先,我們要明確在漢明重量數(shù)組的中間值為2的情況下,L集合因為集合內元素的最低值為0、最高值為2,其均值范圍為0-2;同理,H集合的均值范圍為3-4。
第三段情況如下:
當3,4這種大于原L集合最大均值的數(shù)歸到L集合中時,會導致L集合的均值必然增大;
失去部分3,4元素的H集合的均值可能變大,變小或不變。
- 因為3是H集合的最低均值,所以當失去元素3時集合均值會增大或者不變(原H集合全是3)。
- 因為4是H集合的最高均值,所以當失去元素4時集合均值會減小或者不變(原H集合全是4)。
第四段情況如下:
當0,1,2這種小于原H集合最小均值的數(shù)歸到H集合中時,會導致H集合的均值必然減小;
失去部分0,1,2元素的L集合的均值可能變大,變小或不變。
- 因為0是L集合的最低均值,所以當失去元素0時集合均值會增大或者不變(原L集合全是0)。
- 因為1是L集合的中間均值,所以當失去元素1時
- 集合均值減小——原L集合均值大于1;
- 集合均值不變——原L集合均值等于1;
- 集合均值增大——原L集合均值小于1;
- 因為2是L集合的最高均值,所以當失去元素2時集合均值會減小或者不變(原L集合全是2)。
綜上來看,第三段的情況下必然會導致L集合的必然增大,H集合三種變化可能性都有,集合均值差總體來看是減小的;第四段的情況下必然會導致H集合的必然減小,H集合三種變化可能性都有,集合均值差總體來看是減小的。
注意:
看上面的解釋的時候可能會疑惑,比如第三段情況,L集合均值增大,H集合也有可能增大,那為什么不會出現(xiàn)均值增大的情況呢?
這種情況在數(shù)組元素基數(shù)足夠大的時候是不用擔心的。當數(shù)組長度無限大時,數(shù)組內0,1,2,3,4這5個元素出現(xiàn)概率是等概的。就像我們投硬幣,擲骰子一樣,基數(shù)足夠大就可以實現(xiàn)。那咱們以這個基礎上再去看,拿情況稍微復雜一些的第四段情況舉例:在基數(shù)足夠大的情況下集合內元素全是唯一值的情況幾乎是不可能的,所以不考慮均值不變的情況,那L集合均值增大減小的概率是對半開的,但是H集合是必然增大的,則綜合來看,集合的均值差必然減小。
小結:
所以只有當ptest數(shù)組內的元素和ptsd數(shù)組內的元素一一相等時,兩集合的均值差才能最大,即猜測密鑰猜測到正確密鑰時,兩集合的均值差才能最大。
第一段或第二段情況可能在ptest數(shù)組中存在部分,但是終究會出現(xiàn)第三段或第四段的情況,導致集合差值減小。
猜測密鑰漢明重量數(shù)組的中間值不為2時的分析
猜測密鑰漢明重量數(shù)組的中間值為0,1,3,4的情況在漢明重量數(shù)組元素基數(shù)足夠大時幾乎不可能出現(xiàn),不過在這里也把出現(xiàn)這種情況分析一下。
其實原因也很簡單,本質上和上面中間值為2時一樣。當中間值為0或1時,就表明數(shù)組中最少一半的值為0或1,但對應位置的正確密鑰漢明重量數(shù)組的元素大概率不可能全是0或1,那大于中間值的猜測密鑰漢明重量數(shù)組對應位置的正確密鑰漢明重量數(shù)組元素全都被劃分到H集合,包括小于3的元素,這就會導致H集合均值的必然減小,L集合均值三種變化皆有可能。這種情況的結論在8.2中已經得出,即集合均值差必然減小。
同理,當中間值為3或4時,就表明數(shù)組中最少一半的值為3或4,最終會導致L集合均值的必然增大,L集合均值三種變化皆有可能,集合均值差必然減小。
數(shù)據(jù)統(tǒng)計
理論說明比較枯燥,也沒有數(shù)據(jù)感受直觀,下面我將展示一些我統(tǒng)計到的數(shù)據(jù):
測試代碼如下,只需要改動主函數(shù)即可:
if __name__ == "__main__":table = pt.PrettyTable()guess = []keyList = [i for i in range(64)]n = len(plainlist)for i in range(64):power_std = []HWout_true = sboxout(n, plainlist, i)for j in range(n):power_std.append(HWfun(HWout_true[j]))DPAlist = []for k in range(64):hw_std = []HWout = sboxout(n, plainlist, k)for m in range(n):hw_std.append(HWfun(HWout[m]))DPAlist.append(DPAfun(n, power_std, hw_std))final_dict = dict(zip(keyList, DPAlist))guess.append(max(final_dict, key=final_dict.get))table.add_column('使用密鑰:', [index for index in keyList])table.add_column('猜測密鑰:', [index for index in guess])print('正確率:{:.2%}'.format(len(set(keyList) & set(guess))/64))print(table)明文數(shù)組長度為9的情況下,64次猜測密鑰的結果及正確率:
#示例數(shù)組: [41, 35, 62, 4, 33, 44, 22, 46, 18][外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳
為追求嚴謹,我把長度1000的明文數(shù)組也放上了,雖然很占地方,長度9和長度1000這兩個數(shù)組也是我在此次實驗中一直使用的明文數(shù)組。
由代碼運行結果可知,長度1000的明文數(shù)組驗證結果是100%的,長度1000的明文數(shù)組驗證結果是48.44%。明文數(shù)組長度越小,其得到的漢明重量數(shù)組的中間值和數(shù)組內元素分布越不“規(guī)范”,猜測密鑰結果并不穩(wěn)定。
我接著測試了10組長度為9的隨機明文數(shù)組,10組長度為1000的隨機明文數(shù)組,得到的結果如下:
明文數(shù)組長度9:
[35.94%, 59.38%, 43.75%, 65.62%, 50.00%, 51.56%, 70.31%, 43.75%, 35.94%, 56.25%] 平均正確率:51.25%明文數(shù)組長度1000:
[100.00%, 100.00%, 100.00%, 100.00%, 100.00%, 100.00%, 100.00%, 100.00%, 100.00%, 100.00%] 平均正確率:100.00%小結:
事實勝于雄辯。
校內實驗,未完整展示所有代碼。若文中有描述錯誤的地方,歡迎斧正。
總結
以上是生活随笔為你收集整理的侧信道实验实验二 S盒DPA侧信道攻击的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 大学什么专业学c语言和机械制图,机械设计
- 下一篇: Pr:视频防抖效果