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