我的Android進階之旅------>Android採用AES+RSA的加密機制對http請求進行加密
本文轉載自部落格:http://blog.csdn.net/ouyang_peng/article/details/50983574
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
前言
最近維護公司APP應用的登入模組,由於測試人員用Fiddler抓包工具抓取到了公司關於登入時候的明文登入資訊。雖然使用的是HTTPS的方式進行http請求的,但還是被Fiddler抓到了明文內容。因此,需要對之前未加密的登入資訊進行加密。在網上搜到一篇關於AES+RSA加密方案的文章,如下面連結所示,按照該方案成功解決了加密問題,在這裡記錄一下。
未加密的抓包截圖
首先來看看未加密時,通過Fiddler抓包獲取的明文資訊如圖1所示:
- 圖1 未加密時候,Fiddler抓包獲取的請求體
- 圖2 未加密時候,Fiddler抓包獲取的請求頭
通過圖1可以明顯地看到所有的http請求資訊都是透明的。如果真的有有心人去盜竊使用者的資訊的話,會造成多大的損失。
加密之後的抓包截圖
- 圖4 加密之後,Fiddler抓包獲取的請求體
- 圖5 加密之後,Fiddler抓包獲取的請求頭
通過圖4,可以看到所有的請求體都通過AES加密後,再使用Base64進行編解碼轉換後的請求體,即使是被有心人去竊取了,也很難在有效的時間內進行破解。
首先來看一張圖,來看看實現該需求用到的幾個常用的加解密名詞
- 圖6 加解密常用名詞
基本需求及概念
隨著Internet網的廣泛應用,資訊保安問題日益突出,以資料加密技術為核心的資訊保安技術也得到了極大的發展。目前的資料加密技術根據加密金鑰型別可分私鑰加密(對稱加密)系統和公鑰加密(非對稱加密)系統。
對稱加密演算法是較傳統的加密體制,通訊雙方在加/解密過程中使用他們共享的單一金鑰,鑑於其演算法簡單和加密速度快的優點,目前仍然是主流的密碼體制之一。最常用的對稱密碼演算法是資料加密標準(DES)演算法,但是由於DES金鑰長度較短,已經不適合當今分散式開放網路對資料加密安全性的要求。最後,一種新的基於Rijndael演算法對稱高階資料加密標準AES
取代了資料加密標準DES。非對稱加密由於加/解金鑰不同(公鑰加密,私鑰解密),金鑰管理簡單,也得到廣泛應用。RSA是非對稱加密系統最著名的公鑰密碼演算法。
AES演算法
AES基本原理及演算法流程
美國國家標準和技術研究所(NIST)經過三輪候選演算法篩選,從眾多的分組密碼中選中Rijndael演算法作為高階加密標準(AES)。Rijndael密碼是一個迭代型分組密碼,分組長度和密碼長度都是可變的,分組長度和密碼長度可以獨立的指定為128位元,192位元或者256位元。AES的加密演算法的資料處理單位是位元組,128位的位元資訊被分成16個位元組,按順序複製到一個4*4的矩陣中,稱為狀態(state),AES的所有變換都是基於狀態矩陣的變換。
用Nr表示對一個數據分組加密的輪數(加密輪數與金鑰長度的關係如表1所示)。在輪函式的每一輪迭代中,包括四步變換,分別是位元組代換運算(ByteSub())、行變換(ShiftRows())、列混合(MixColumns())以及輪金鑰的新增變換AddRoundKey()[3],其作用就是通過重複簡單的非線形變換、混合函式變換,將位元組代換運算產生的非線性擴散,達到充分的混合,在每輪迭代中引入不同的金鑰,從而實現加密的有效性。
表1 是三種不同型別的AES加密金鑰分組大小與相應的加密輪數的對照表。加密開始時,輸入分組的各位元組按表2 的方式裝入矩陣state中。如輸入ABCDEFGHIJKLMNOP,則輸入塊影射到如表2的狀態矩陣中。
表1:
AES型別 | 金鑰長度 | 分組長度 | 加密輪數 |
---|---|---|---|
AES-128 | 4字 | 4字 | 10 |
AES-192 | 6字 | 4字 | 12 |
AES-256 | 8字 | 4字 | 14 |
表2:
A | E | I | M |
---|---|---|---|
B | F | J | N |
C | G | K | O |
D | H | L | P |
-
1、位元組代換運算(ByteSub())
位元組代換運算是一個可逆的非線形位元組代換操作,對分組中的每個位元組進行,對位元組的操作遵循一個代換表,即S盒。S盒由有限域 GF(28)上的乘法取逆和GF(2)上的仿射變換兩步組成。
-
2、行變換ShiftRows()
行變換是一種線性變換,其目的就是使密碼資訊達到充分的混亂,提高非線形度。行變換對狀態的每行以位元組為單位進行迴圈右移,移動位元組數根據行數來確定,第0行不發生偏移,第一行迴圈右移一個位元組,第二行移兩個,依次類推。
+3、 列混合變換MixColumns()
列變換就是從狀態中取出一列,表示成多項式的形式後,用它乘以一個固定的多項式a(x),然後將所得結果進行取模運算,模值為 x4+1。其中a(x)={03}x3+{02}x2+{01}x+{02},
這個多項式與x4+1互質,因此是可逆的。列混合變換的算術表示式為:s’(x)= a(x) s(x),其中, s(x)表示狀態的列多項式。
- 4、輪金鑰的新增變換AddRoundKey()
在這個操作中,輪金鑰被簡單地異或到狀態中,輪金鑰根據金鑰表獲得,其長度等於資料塊的長度Nb。
AES演算法流程
對於傳送方,它首先建立一個AES私鑰,並用口令對這個私鑰進行加密。然後把用口令加密後的AES金鑰通過Internet傳送到接收方。傳送方解密這個私鑰,並用此私鑰加密明文得到密文,密文和加密後的AES金鑰一起通過Internet傳送到接收方。接收方收到後再用口令對加密金鑰進行解密得到AES金鑰,最後用解密後的金鑰把收到的密文解密成明文。圖7中是這個過程的實現流程。- 圖7 AES演算法流程
RSA演算法
RSA演算法基本原理及流程
RSA是在1977年發明RSA密碼系統的三個人的名字的首字母的縮寫,他們是:Ron Rivest、Adi Shamir和Leonard Adleman。它是第一個公鑰加密演算法,在很多密碼協議中都有應用,如SSL和S/MIME。RSA演算法是基於大質數的因數分解的公匙體系。簡單的講,就是兩個很大的質數,一個作為公鑰,另一個作為私鑰,如用其中一個加密,則用另一個解密。金鑰長度從40到2048位可變,金鑰越長,加密效果越好,但加密解密的開銷也大。RSA演算法可簡單描述如下:
公開金鑰:n=pq,(p,q為兩個不同的很大的質數,p和q必須保密)
將(p-1)和(q-1)相乘得到φ(n)
選擇一個整數e (1<e<φ(n))與φ(n)互質
祕密金鑰:d=e-1modφ(n),即計算一個數字d,使得它滿足公式 de=1 modφ(n)
加密:c=mc(mod n)
解密:m=cd(mod n),m為明文,c為密文。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
RSA演算法實現流程
首先,接收方建立RSA密匙對,即一個公鑰和一個私鑰,公鑰被髮送到傳送方,私鑰則被儲存在接收方。傳送方在接收到這個公鑰後,用該公鑰對明文進行加密得到密文,然後把密文通過網路傳輸給接收方。接收方在收到它們後,用RSA私鑰對收到的密文進行解密,最後得到明文。圖8是整個過程的實現流程。
- 圖8 RSA演算法實現流程
AES與RSA相結合資料加密方案
RSA演算法是公開金鑰系統的代表,其安全性建立在具有大素數因子的合數,其因子分解困難這一法則之上的。Rijndael演算法作為新一代的高階加密標準,執行時不需要計算機有非常高的處理能力和大的記憶體,操作可以很容易的抵禦時間和空間的攻擊,在不同的執行環境下始終能保持良好的效能。這使AES將安全,高效,效能,方便,靈活性集於一體,理應成為網路資料加密的首選。相比較,因為AES金鑰的長度最長只有256位元,可以利用軟體和硬體實現高速處理,而RSA演算法需要進行大整數的乘冪和求模等多倍字長處理,處理速度明顯慢於AES[5];所以AES演算法加解密處理效率明顯高於RSA演算法。在金鑰管理方面,因為AES演算法要求在通訊前對金鑰進行祕密分配,解密的私鑰必須通過網路傳送至加密資料接收方,而RSA採用公鑰加密,私鑰解密(或私鑰加密,公鑰解密),加解密過程中不必網路傳輸保密的金鑰;所以RSA演算法金鑰管理要明顯優於AES演算法。
從上面比較得知,由於RSA加解密速度慢,不適合大量資料檔案加密,因此在網路中完全用公開密碼體制傳輸機密資訊是沒有必要,也是不太現實的。AES加密速度很快,但是在網路傳輸過程中如何安全管理AES金鑰是保證AES加密安全的重要環節。這樣在傳送機密資訊的雙方,如果使用AES對稱密碼體制對傳輸資料加密,同時使用RSA不對稱密碼體制來傳送AES的金鑰,就可以綜合發揮AES和RSA的優點同時避免它們缺點來實現一種新的資料加密方案。加解密實現流程如圖(9)。
- 圖9 AES與RSA相結合資料加密方案流程
具體過程是先由接收方建立RSA金鑰對,接收方通過Internet傳送RSA公鑰到傳送方,同時儲存RSA私鑰。而傳送方建立AES金鑰,並用該AES金鑰加密待傳送的明文資料,同時用接受的RSA公鑰加密AES金鑰,最後把用RSA公鑰加密後的AES金鑰同密文一起通過Internet傳輸傳送到接收方。當接收方收到這個被加密的AES金鑰和密文後,首先呼叫接收方儲存的RSA私鑰,並用該私鑰解密加密的AES金鑰,得到AES金鑰。最後用該AES金鑰解密密文得到明文。
Android端 AES+RSA結合實踐
基本要求
- 保證傳輸資料的安全性
- 保證資料的完整性
- 能夠驗證客戶端的身份
基本流程
Android端
- 伺服器端(server)分別生成自己的RSA金鑰對,並提供介面給Android客戶端獲取RSA公鑰(rsaPublicKey)
- client生成AES金鑰(aesKey)
- client使用自己的AES金鑰(aesKey)對轉換為json格式的請求明文資料(data)進行加密,得到加密後的請求資料encryptData
- client使用server提供的介面獲取RSA公鑰(rsaPublicKey)
- client使用獲取RSA公鑰(rsaPublicKey)對AES金鑰(aesKey)進行加密,得到encryptAesKey
- client將encryptAesKey作為http請求頭引數,將加密後的請求資料encryptData作為請求體一起傳輸給伺服器端
伺服器端
- server響應client的http請求,讀取http請求頭。獲得client傳過來的加密後的AES金鑰(encryptAesKey),讀取http請求體,獲得client傳過來的加密後的請求資料(encryptData)。
- server使用自己的RSA私鑰(rsaPrivateKey)對加密後的AES金鑰(encryptAesKey)進行RSA解密,得到AES金鑰(aesKey)
- 使用解密後的AES金鑰(aesKey)對加密後的請求資料(encryptData),進行AES解密操作,得到解密後的請求資料(data),該資料為json格式
- 對解密後的請求資料(data)進行json解析,然後做相關的響應操作。
基本上如下圖所示的流程:
由於公司程式碼設計的內容太多,不好貼在此處。大家可以參考參考下面的這個github上面的連結學習一下,本人的實現方式也是參考了下面的程式碼,具體的流程還是要和伺服器人員配合一起出方案,進行AES和RSA加密的時候,注意一定要和伺服器那邊的加密演算法要一致,否則伺服器可能無法進行解密操作。