網絡傳輸數據加解密方案選擇(RSA+AES)

爲什麼要對數據加密

理由很簡單,爲了安全。
因爲之前一直在趕項目,沒有對傳輸的數據做處理,導致我這邊通過抓包軟件直接能看到我請求發的是什麼數據,服務端給我返回的數據是什麼。

而且可以通過抓包軟件修改響應數據返回給客戶端,這樣一來,客戶端實際上接收到的數據並不是服務端給我的源數據,而是被第三者修改過的數據,如此一來,數據傳輸的安全就很有必要了。

那如何保證數據傳輸的安全呢?
總體要做到一下兩點

1. 保證傳輸的數據是經過加密或者編碼過的,即使有人通過抓包軟件抓取到數據,也看不懂或者很難解開的。
2. 要能夠確定接收到的數據沒有經過篡改,也就是確認發送者的身份

雖然說沒有絕對的安全,但是做到以上兩點,我們能夠極大程度的提高數據的安全性以及對身份的確定性


加密算法的選擇

市面上的加密算法衆多,但是就目前來講加密大致分爲以下兩種:

1. 對稱加密
2. 非對稱加密

關於對稱加密和非對稱加密的原理等文章有很多,這裏我就不展開介紹了,可以看看下面的文章,都寫的很好!
感謝以下文章作者的分享!

常用加密算法概述
淺談常見的七種加密算法及實現
MD5算法和SHA-1算法
對稱加密及AES加密算法
從支付寶SDK的支付流程理解什麼是公鑰和私鑰,什麼是加密和數字簽名
非對稱加密及RSA加密算法

這裏我們就不再去糾結算法的原理是什麼了,說實話,我也看不懂(很難受)
在這裏插入圖片描述

我們的目的就是選擇一個合適的方案並且能夠合理的用在項目中就行了。

所以,我們先來簡單的根據上面的文章來總結一下加解密的相關知識

祕鑰

下面的解釋來自百度百科:
祕鑰,即密鑰,在密碼學中,密鑰(key,又常稱金鑰)是指某個用來完成加密、解密、完整性驗證等密碼學應用的祕密信息。在對稱密碼學(或稱密鑰密碼學)中,加密和解密用的是同一個鑰匙,因此鑰匙需要保密。而在公鑰密碼學(或稱非對稱密碼學)中,加密和解密用的鑰匙不同:通常一個是公開的,稱爲公鑰;另一個保密,稱爲私鑰。


對稱加密

加密和解密都是使用一個祕鑰

優點: 對數據沒有長度限制,加解密速度快
缺點: 祕鑰的傳輸及保管是個問題,任何一方的祕鑰泄漏都將導致數據的不安全

在衆多的對稱加密算法中,目前來講AES是最好的,最安全的,因爲它是最新出的。
一般來講,新出的都會比以前的好。

在這裏插入圖片描述

實際上是因爲DES的祕鑰相對較短,也就相對更容易破解,因此,目前更推薦使用AES進行對稱加密。

不過需要注意的是,AES在不同的Android版本上需要注意兼容性的問題,這個後面再講


非對稱加密

非對稱加密首先要生成一對祕鑰,分爲公鑰和私鑰
公鑰和私鑰能夠相互解密
一般來講,長度長的作爲私鑰,要放在服務端保管好,千萬不能泄露。長度短的作爲公鑰,分發給客戶端,公鑰是公開的。
支付寶給我們提供了生成RSA祕鑰的工具,一鍵生成RSA祕鑰
需要的可以下載。
嫌麻煩的也可以使用在線生成RSA祕鑰

注意事項:
生成的祕鑰大概如下,根據你自己的需求生成
祕鑰位數: 一般來講祕鑰的長度選擇爲1024位或2048位。2048位的安全性更高,支付寶也建議使用2048位來生成祕鑰。不過這裏有個坑,網上的大部分RSA工具類在使用2048位祕鑰進行解密的時候都會報錯,這個坑我們後面再來解決。
祕鑰格式: 我們選擇目前比較流行的PKCS#8即可,如果出現問題,就選擇pkcs#1格式

在這裏插入圖片描述

說了這麼多,我們來看看非對稱祕鑰的優缺點:

  • 優點:無需關心祕鑰的傳輸問題,只要在服務端把私鑰保管好即可
  • 缺點:加密速度慢,對加密的數據長度有限制

加密方案選擇

好了,瞭解可加密的相關知識,下面我們來分幾個安全等級來排列一下下面的加密方案(安全等級依次提升)

方案一,使用Base64編碼

這裏我們引入一下編碼,我們在使用加密的時候一般都要對加密後的數據進行一下編碼,防止傳輸的過程中出現亂碼的情況。
最常用的就是Base64編碼了,Base64不算是加密,只是把字符經過編碼變成不可讀一串文字。
如果你的項目對安全根本沒有什麼要求,你就可以使用編碼的方式,簡單省事。但是這個方式只是比“裸奔”好那麼一點,可以防止大部分小白用戶吧。

方案二,雙方約定好密碼,使用AES加密

這種方案要求服務端和客戶端約定好加密的密碼,兩端分別保留,在處理數據時就用本地約定好的密碼對數據進行加解密。
這中方案能應付一些對安全要求不是很高的項目。由於密碼是分別放在兩端的,一些別有用心之心如果通過一些手段(例如Android端通過反編譯或者逆向)獲取到了密碼,那麼,數據安全也就是空談了,可以直接通過 在線AES加密解密 網站或者寫個程序破解傳輸的數據了。
在線AES加密解密 這個網站我們可以收藏一下,後面調試項目的時候很可能會用上。

方案三,使用AES加密,密碼隨機生成

這種方案可以在服務端和客戶端中寫一個隨機函數,生成一個隨機的密碼,兩端均通過這個隨機密碼進行加密,然後傳輸數據的時候把這個隨機密碼傳輸給對方(例如放到請求頭中),對方用接收到的隨機密碼進行解密。

實際上這個方案有點掩耳盜鈴的意思,你都把解密的密碼放到請求頭中去了,人家一抓包很容易就獲取到密碼,甚至比方案二還要容易。

方案四,RSA結合AES進行加密,實現對服務端的單向認證

我們知道了RSA雖然能過做到身份驗證,但是其加密速度較慢,並且不適合對大數據進行加密。
那麼,單純的使用RSA加密肯定是不可取的。
而AES的加密速度快且對加密數據沒有大小限制,但是,祕鑰的傳輸及管理是個問題,上面我們已經舉過例子了。
那麼,我們把兩者結合起來取長補短不就好了嗎?

我們可以這樣:
以服務端給客戶端傳輸數據爲例

  1. 服務端生成一對RSA祕鑰,私鑰放在服務端,公鑰下發給客戶端
  2. 服務端使用隨機函數生成AES加密要用的key
  3. 服務端使用隨機的key對要傳輸的數據用AES進行加密
  4. 使用服務端的私鑰對生成的隨機Key進行加密。這裏我爲什麼更傾向於使用RSA加密而不是簽名呢?因爲我個人覺得簽名的話還要把簽名的數據和加密後的數據一起傳給客戶端,會增加傳輸數據的大小,其實,只要是客戶端能夠成功的解密,實際上就已經能夠確認服務端的身份了。如果別修改過後重新加密再傳輸給你,你是肯定解密失敗的。前提是服務端私鑰沒有泄漏
  5. 服務端將使用AES加密的數據以及使用RSA加密的隨機key一起發給客戶端
  6. 客戶端拿到數據後,先使用公鑰對加密的隨機key進行解密,解密成功即可確定是服務端發來的數據,沒有經過他人修改,然後使用解密成功的隨機key對使用AES加密的數據進行解密,獲取最終的數據

這種方案實際上已經很安全了,實現了對服務端身份的單向認證以及對傳輸數據的加密,基本上可以應付絕大部分的項目了

方案五,RSA結合AES,實現雙向驗證

方案四實際上已經足夠安全,實現了客戶端對服務端的身份驗證,但是如果你的服務端也要對客戶端的身份進行驗證,那麼,你可以使用這個方案。

該方案實際上就是在方案四的基礎上多了一對RSA祕鑰,要求服務端和客戶端都生成一對祕鑰,服務端保管好自己生成的私鑰,把公鑰給客戶端,客戶端也保管好自己生成的私鑰,把公鑰給服務端。

大概流程如下;
本次以客戶端給服務端傳輸數據爲例

  1. 兩端均生成一對RSA祕鑰,各自保管好私鑰,把公鑰發給對方
  2. 客戶端使用隨機函數生成AES加密要用的key
  3. 客戶端使用隨機的key對要傳輸的數據用AES進行加密
  4. 客戶端使用私鑰對生成的隨機Key進行加密。
  5. 客戶端將使用AES加密的數據以及使用客戶端私鑰加密的隨機key一起發給服務端
  6. 服務端拿到數據後,先使用客戶端提供的公鑰對加密的隨機key進行解密,解密成功即可確認客戶端的身份,沒有經過他人修改,然後使用解密成功的隨機key對使用AES加密的數據進行AES解密,獲取最終的數據

服務端給客戶端返回數據也是類似。
總結來講就是:

  1. 兩端各自用自己的RSA私鑰對AES隨機key進行加密
  2. 兩端各自使用對方提供的RSA公鑰對加密的隨機Key數據進行解密
  3. 剩下的都一樣,就是使用解密的得到的AES密碼進行解密了

基本上加密的方案就這麼多,足夠你使用了,選一個適合你項目的即可,本篇博客主要就是介紹加密方案的選擇,下一篇博客,我們來代碼進行實戰,以及解決實戰中遇到的坑

Android完美使用RSA2結合AES對數據進行加密(兼容RSA2 SHA256WithRSA,可使用2048長度的祕鑰,AES Android各版本通用)


如果你覺得本文對你有幫助,麻煩動動手指頂一下,算是對本文的一個認可,如果文中有什麼錯誤的地方,還望指正,轉載請註明轉自喻志強的博客 ,謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章