天天看點

我的Android進階之旅------>Android采用AES+RSA的加密機制對http請求進行加密前言基本需求及概念AES算法RSA算法AES與RSA相結合資料加密方案Android端 AES+RSA結合實踐更多參考

<a href="#%E5%89%8D%E8%A8%80">前言</a>

<a href="#%E6%9C%AA%E5%8A%A0%E5%AF%86%E7%9A%84%E6%8A%93%E5%8C%85%E6%88%AA%E5%9B%BE">未加密的抓包截圖</a>

<a href="#%E5%8A%A0%E5%AF%86%E4%B9%8B%E5%90%8E%E7%9A%84%E6%8A%93%E5%8C%85%E6%88%AA%E5%9B%BE">加密之後的抓包截圖</a>

<a href="#%E5%9F%BA%E6%9C%AC%E9%9C%80%E6%B1%82%E5%8F%8A%E6%A6%82%E5%BF%B5">基本需求及概念</a>

<a href="#aes%E7%AE%97%E6%B3%95">AES算法</a>

<a href="#aes%E5%9F%BA%E6%9C%AC%E5%8E%9F%E7%90%86%E5%8F%8A%E7%AE%97%E6%B3%95%E6%B5%81%E7%A8%8B">AES基本原理及算法流程</a>

<a href="#aes%E7%AE%97%E6%B3%95%E6%B5%81%E7%A8%8B">AES算法流程</a>

<a href="#rsa%E7%AE%97%E6%B3%95">RSA算法</a>

<a href="#rsa%E7%AE%97%E6%B3%95%E5%9F%BA%E6%9C%AC%E5%8E%9F%E7%90%86%E5%8F%8A%E6%B5%81%E7%A8%8B">RSA算法基本原理及流程</a>

<a href="#rsa%E7%AE%97%E6%B3%95%E5%AE%9E%E7%8E%B0%E6%B5%81%E7%A8%8B">RSA算法實作流程</a>

<a href="#aes%E4%B8%8Ersa%E7%9B%B8%E7%BB%93%E5%90%88%E6%95%B0%E6%8D%AE%E5%8A%A0%E5%AF%86%E6%96%B9%E6%A1%88">AES與RSA相結合資料加密方案</a>

<a href="#android%E7%AB%AF-aesrsa%E7%BB%93%E5%90%88%E5%AE%9E%E8%B7%B5">Android端 AESRSA結合實踐</a>

<a href="#%E5%9F%BA%E6%9C%AC%E8%A6%81%E6%B1%82">基本要求</a>

<a href="#%E5%9F%BA%E6%9C%AC%E6%B5%81%E7%A8%8B">基本流程</a>

<a href="#android%E7%AB%AF">Android端</a>

<a href="#%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%AB%AF">伺服器端</a>

<a href="#java%E7%89%88%E7%A4%BA%E4%BE%8B">java版示例</a>

<a href="#%E6%9B%B4%E5%A4%9A%E5%8F%82%E8%80%83">更多參考</a>

最近維護公司APP應用的登入子產品,由于測試人員用Fiddler抓包工具抓取到了公司關于登入時候的明文登入資訊。雖然使用的是HTTPS的方式進行http請求的,但還是被Fiddler抓到了明文内容。是以,需要對之前未加密的登入資訊進行加密。在網上搜到一篇關于AES+RSA加密方案的文章,如下面連結所示,按照該方案成功解決了加密問題,在這裡記錄一下。

<a href="https://wustrive2008.github.io/2015/08/21/%E5%BC%80%E6%94%BE%E6%8E%A5%E5%8F%A3%E7%9A%84%E5%AE%89%E5%85%A8%E9%AA%8C%E8%AF%81%E6%96%B9%E6%A1%88%28AES+RSA%29/">開放接口的安全驗證方案(AES+RSA)</a>

首先來看看未加密時,通過Fiddler抓包擷取的明文資訊如圖1所示:

圖1 未加密時候,Fiddler抓包擷取的請求體

我的Android進階之旅------&amp;gt;Android采用AES+RSA的加密機制對http請求進行加密前言基本需求及概念AES算法RSA算法AES與RSA相結合資料加密方案Android端 AES+RSA結合實踐更多參考

圖2 未加密時候,Fiddler抓包擷取的請求頭

我的Android進階之旅------&amp;gt;Android采用AES+RSA的加密機制對http請求進行加密前言基本需求及概念AES算法RSA算法AES與RSA相結合資料加密方案Android端 AES+RSA結合實踐更多參考

通過圖1可以明顯地看到所有的http請求資訊都是透明的。如果真的有有心人去盜竊使用者的資訊的話,會造成多大的損失。

圖4 加密之後,Fiddler抓包擷取的請求體

我的Android進階之旅------&amp;gt;Android采用AES+RSA的加密機制對http請求進行加密前言基本需求及概念AES算法RSA算法AES與RSA相結合資料加密方案Android端 AES+RSA結合實踐更多參考

圖5 加密之後,Fiddler抓包擷取的請求頭

我的Android進階之旅------&amp;gt;Android采用AES+RSA的加密機制對http請求進行加密前言基本需求及概念AES算法RSA算法AES與RSA相結合資料加密方案Android端 AES+RSA結合實踐更多參考

通過圖4,可以看到所有的請求體都通過AES加密後,再使用Base64進行編解碼轉換後的請求體,即使是被有心人去竊取了,也很難在有效的時間内進行破解。

首先來看一張圖,來看看實作該需求用到的幾個常用的加解密名詞

圖6 加解密常用名詞

我的Android進階之旅------&amp;gt;Android采用AES+RSA的加密機制對http請求進行加密前言基本需求及概念AES算法RSA算法AES與RSA相結合資料加密方案Android端 AES+RSA結合實踐更多參考
随着Internet網的廣泛應用,資訊安全問題日益突出,以資料加密技術為核心的資訊安全技術也得到了極大的發展。目前的資料加密技術根據加密密鑰類型可分私鑰加密(對稱加密)系統和公鑰加密(非對稱加密)系統。 對稱加密算法是較傳統的加密體制,通信雙方在加/解密過程中使用他們共享的單一密鑰,鑒于其算法簡單和加密速度快的優點,目前仍然是主流的密碼體制之一。最常用的對稱密碼算法是資料加密标準(DES)算法,但是由于DES密鑰長度較短,已經不适合當今分布式開放網絡對資料加密安全性的要求。最後,一種新的基于Rijndael算法對稱進階資料加密标準AES取代了資料加密标準DES。非對稱加密由于加/解密鑰不同(公鑰加密,私鑰解密),密鑰管理簡單,也得到廣泛應用。RSA是非對稱加密系統最著名的公鑰密碼算法。

美國國家标準和技術研究所(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字

10

AES-192

6字

12

AES-256

8字

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密鑰通過Internet發送到接收方。發送方解密這個私鑰,并用此私鑰加密明文得到密文,密文和加密後的AES密鑰一起通過Internet發送到接收方。接收方收到後再用密碼對加密密鑰進行解密得到AES密鑰,最後用解密後的密鑰把收到的密文解密成明文。圖7中是這個過程的實作流程。

圖7 AES算法流程

我的Android進階之旅------&amp;gt;Android采用AES+RSA的加密機制對http請求進行加密前言基本需求及概念AES算法RSA算法AES與RSA相結合資料加密方案Android端 AES+RSA結合實踐更多參考

RSA是在1977年發明RSA密碼系統的三個人的名字的首字母的縮寫,他們是:Ron Rivest、Adi Shamir和Leonard Adleman。它是第一個公鑰加密算法,在很多密碼協定中都有應用,如SSL和S/MIME。RSA算法是基于大質數的因數分解的公匙體系。簡單的講,就是兩個很大的質數,一個作為公鑰,另一個作為私鑰,如用其中一個加密,則用另一個解密。密鑰長度從40到2048位可變,密鑰越長,加密效果越好,但加密解密的開銷也大。RSA算法可簡單描述如下:

首先,接收方建立RSA密匙對,即一個公鑰和一個私鑰,公鑰被發送到發送方,私鑰則被儲存在接收方。發送方在接收到這個公鑰後,用該公鑰對明文進行加密得到密文,然後把密文通過網絡傳輸給接收方。接收方在收到它們後,用RSA私鑰對收到的密文進行解密,最後得到明文。圖8是整個過程的實作流程。

圖8 RSA算法實作流程

我的Android進階之旅------&amp;gt;Android采用AES+RSA的加密機制對http請求進行加密前言基本需求及概念AES算法RSA算法AES與RSA相結合資料加密方案Android端 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相結合資料加密方案流程

我的Android進階之旅------&amp;gt;Android采用AES+RSA的加密機制對http請求進行加密前言基本需求及概念AES算法RSA算法AES與RSA相結合資料加密方案Android端 AES+RSA結合實踐更多參考

具體過程是先由接收方建立RSA密鑰對,接收方通過Internet發送RSA公鑰到發送方,同時儲存RSA私鑰。而發送方建立AES密鑰,并用該AES密鑰加密待傳送的明文資料,同時用接受的RSA公鑰加密AES密鑰,最後把用RSA公鑰加密後的AES密鑰同密文一起通過Internet傳輸發送到接收方。當接收方收到這個被加密的AES密鑰和密文後,首先調用接收方儲存的RSA私鑰,并用該私鑰解密加密的AES密鑰,得到AES密鑰。最後用該AES密鑰解密密文得到明文。

保證傳輸資料的安全性

保證資料的完整性

能夠驗證用戶端的身份

伺服器端(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解析,然後做相關的響應操作。

基本上如下圖所示的流程:

我的Android進階之旅------&amp;gt;Android采用AES+RSA的加密機制對http請求進行加密前言基本需求及概念AES算法RSA算法AES與RSA相結合資料加密方案Android端 AES+RSA結合實踐更多參考

由于公司代碼設計的内容太多,不好貼在此處。大家可以參考參考下面的這個github上面的連結學習一下,本人的實作方式也是參考了下面的代碼,具體的流程還是要和伺服器人員配合一起出方案,進行AES和RSA加密的時候,注意一定要和伺服器那邊的加密算法要一緻,否則伺服器可能無法進行解密操作。

<a href="https://github.com/wustrive2008/aes-rsa-java">AES+RSA雙重加密Java示例</a>

<a href="http://my.oschina.net/nicsun/blog/95632">關于AES256算法java端加密,ios端解密出現無法解密問題的解決方案</a>

<a href="http://my.oschina.net/nicsun/blog/95632">http://my.oschina.net/nicsun/blog/95632</a>

<a href="http://blog.csdn.net/aflight/article/details/13626385">Java 運用 Bouncy Castle 進行 AES128 加密解密(CBC 模式 PKCS7 填充 )</a>

<a href="http://blog.csdn.net/aflight/article/details/13626385">http://blog.csdn.net/aflight/article/details/13626385</a>

<a href="http://www.jianshu.com/p/ec7bb7325ff2">安全篇-AES/RSA加密機制</a>

<a href="http://www.jianshu.com/p/ec7bb7325ff2">http://www.jianshu.com/p/ec7bb7325ff2</a>
<a href="https://wustrive2008.github.io/2015/08/21/%E5%BC%80%E6%94%BE%E6%8E%A5%E5%8F%A3%E7%9A%84%E5%AE%89%E5%85%A8%E9%AA%8C%E8%AF%81%E6%96%B9%E6%A1%88(AES+RSA)/">https://wustrive2008.github.io/2015/08/21/%E5%BC%80%E6%94%BE%E6%8E%A5%E5%8F%A3%E7%9A%84%E5%AE%89%E5%85%A8%E9%AA%8C%E8%AF%81%E6%96%B9%E6%A1%88(AES+RSA)/</a>

<a href="http://hello-nick-xu.iteye.com/blog/2103775">Java加密解密快速入門【包括MD5、BASE64、DES、RSA等算法】 上篇</a>

<a href="http://hello-nick-xu.iteye.com/blog/2103775">http://hello-nick-xu.iteye.com/blog/2103775</a>

<a href="http://hello-nick-xu.iteye.com/blog/2103781">Java加密解密快速入門【包括MD5、BASE64、DES、RSA等算法】 下篇</a>

<a href="http://hello-nick-xu.iteye.com/blog/2103781">http://hello-nick-xu.iteye.com/blog/2103781</a>

<a href="http://www.cnblogs.com/arix04/archive/2009/10/15/1511839.html">【java】AES加密解密|及Base64的使用</a>

<a href="http://www.cnblogs.com/arix04/archive/2009/10/15/1511839.html">http://www.cnblogs.com/arix04/archive/2009/10/15/1511839.html</a>

<a href="http://www.cnblogs.com/jys509/p/4768120.html">.NET/android/java/iOS AES通用加密解密</a>

<a href="http://www.cnblogs.com/jys509/p/4768120.html">http://www.cnblogs.com/jys509/p/4768120.html</a>

<a href="http://www.cnblogs.com/makemelike/articles/3802518.html">IOS &amp; JAVA RSA Encryption &amp; Decryption</a>

<a href="http://www.cnblogs.com/makemelike/articles/3802518.html">http://www.cnblogs.com/makemelike/articles/3802518.html</a>

<a href="http://cryptojs.altervista.org/publickey/doc/doc_rsa_java.html">doc_rsa_java</a>

<a href="http://cryptojs.altervista.org/publickey/doc/doc_rsa_java.html">http://cryptojs.altervista.org/publickey/doc/doc_rsa_java.html</a>

<a href="http://www.mamicode.com/info-detail-514466.html">密碼算法詳解——AES</a>

<a href="http://www.mamicode.com/info-detail-514466.html">http://www.mamicode.com/info-detail-514466.html</a>