如何保證APP與API通信安全?
TOKEN作為用戶身份憑證并不能保證數據安全,別人通過抓包等方式很容易拿到TOKEN,帶上TOKEN請求我們的API接口就能獲取數據;其實換一個角度想:我們只需保證即使TOKEN被別人冒用,也不能調用我們API接口就行。
分享一個前后端使用AES和RSA混合加密通信的方案。
AES對稱加密首先看一下AES加密的示意圖:
加密過程為:發送方(APP)使用密鑰對參數明文進行AES加密獲得密文,然后將密文和密鑰一起發給接收方(服務端),接收方使用密鑰對密文進行AES解密,得到參數明文。
AES由于是對稱加密算法,特點就是加解密運算速度快;由于加解密使用的是同一個密鑰,所以缺點就是在傳輸過程中會存在密鑰泄露的風險。
RSA非對稱加密同樣的,先來看一下RSA加密的示意圖:
首先接收方(服務端)生成一對RSA密鑰(公鑰、私鑰),私鑰自己保存同時公鑰公布給發送方(APP)。
加密過程:發送方使用接收方公鑰將參數明文進行RSA加密得到密文,并將密文發送給接收方,接收方使用自己的私鑰對密文進行RSA解密得到參數明文。
同樣的,服務端返回數據給APP時也可以使用私鑰對數據進行簽名,APP可以使用服務端的公鑰來驗證簽名,從而判斷數據是否來自合法的服務端。
RSA是非對稱加密算法,加解密大量數據速度較慢,但由于加解密使用不同的密鑰,所以安全度較高。
介于這兩種加密方式各有優缺點,所以前后端加密通信方案通常采用AES對稱加密算法對參數進行加密,RSA非對稱加密算法則只用來對AES密鑰進行加密,兩種加密方式混合使用既不會太影響通信速度,又保證了通信安全。
為了防止重放攻擊,我們還需要在AES+RSA混合加密的基礎上再加入時間戳、隨機字符串以及數字簽名等校驗邏輯。
為了防止中間人攻擊,首先HTTPS是必須的,除此之外前后端還需要互相進行身份認證,確保通信沒有被劫持。
前后端加密通信完整流程準備工作:服務端生成RSA密鑰對(公鑰、私鑰),公鑰下發給APP,自己持有私鑰;APP也需要生成RSA密鑰對(公鑰、私鑰),公鑰上傳到服務端保存、私鑰自己保留。
首先展示一下我用代碼實現的前后端完整的加解密通信流程:
首先講一下APP調用接口時的加密流程:
隨機生成一個AES加密算法的密鑰,用于后續加密;使用服務端的RSA公鑰對步驟1中生成的AES密鑰明文進行RSA加密生成密鑰密文;使用AES密鑰明文對參數明文進行AES加密生成參數密文;生成當前時間的時間戳;生成一串隨機字符串;將參數密文、AES密鑰密文、時間戳、隨機字符串進行MD5計算,得到md5值;使用APP自己的RSA私鑰對md5值簽名,得到簽名值;最后將參數密文、AES密鑰密文、時間戳、隨機字符串、簽名值一起發送到服務端;再來講一下服務端收到請求后的解密流程:
對比請求參數中時間戳與服務器端獲取的當前時間戳,判斷兩者差值是否在一定的時間之內,超過則認為請求過期;從系統緩存中查找參數中隨機字符串是否已存在,如果已存在則認為是一次重復請求,不存在則將該隨機字符串放入緩存;將參數密文、AES密鑰密文、時間戳、隨機字符串進行MD5計算,得到md5值使用客戶端上傳的RSA公鑰驗證參數中的簽名是否來自合法授權的客戶端,防止非法客戶端篡改數據;使用自己的RSA私鑰解密AES密鑰密文,得到AES明文密鑰;使用AES明文密鑰解密參數密文得到參數明文;進行正常的業務處理流程;返回數據加密流程與客戶端加密流程一致;總結要保證APP與API通信安全,首先要使用HTTPS協議,同時前后端還需要使用AES+RSA混合加密的方式來對數據進行加密,另外為了防止重放攻擊、中間人攻擊,還需要在數據加密的基礎上加入時間戳、隨機字符串以及數字簽名等校驗手段進一步提高通信的安全性。