前言
在日常業(yè)務(wù)中突那,經(jīng)常會(huì)抓包查看APP的網(wǎng)絡(luò)請求,如果一些重要信息雖然加密過了秃诵,但是如果出現(xiàn)過加密方式及數(shù)據(jù)被泄露難以防范別有用心的人使用腳本調(diào)用搞破壞肥矢,比如某個(gè)人拿到了你的mac地址及登錄賬號和密碼,這樣就可以模擬APP的正常請求而服務(wù)端無法識(shí)別到底是腳本還是正常的APP
解決方案:
將每次傳遞的mac都是變化的掰茶,而且傳遞的mac等信息還添加上時(shí)效性暇藏,比如有效期為3秒,這樣就算別人拿到了你的信息也沒法長期盜用
一濒蒋、mac地址的傳遞
1盐碱、本地生成一個(gè)時(shí)間戳及隨機(jī)數(shù)的秘鑰
2、生成的秘鑰使用第1步生成的秘鑰進(jìn)行AES加密沪伙,然后使用Base64的方式生成字符串
3瓮顽、將第1步生成的秘鑰使用一個(gè)前后端約定的生成的秘鑰加密,比如當(dāng)前日期和版本號或上線前下發(fā)的秘鑰進(jìn)行加密
4围橡、將第2步和第3步的加密后的mac地址和加密后的秘鑰傳遞給后端
5暖混、后端收到請求后先通過約定的規(guī)則反向解密得到原生的秘鑰,并驗(yàn)證秘鑰的時(shí)間期限是否在約定的比如2秒返回內(nèi)
6翁授、使用解密得到的秘鑰再對加密后的mac地址進(jìn)行解密得到真正的mac地址
二拣播、RSA秘鑰
在第一步拿到mac地址后下發(fā)RSA秘鑰
三晾咪、通過第二步拿到的RSA秘鑰請求一般網(wǎng)絡(luò)請求使用的AES秘鑰
四、對第三步拿到的AES秘鑰對一般請求進(jìn)行加密解密
注意點(diǎn):
1贮配、在一些特殊核心業(yè)務(wù)谍倦,比如微信支付寶的發(fā)紅包、轉(zhuǎn)賬泪勒、付款等場景時(shí)昼蛀,對Mac的加密秘鑰進(jìn)行強(qiáng)時(shí)效性檢查
2、發(fā)現(xiàn)某些版本的前后端約定的秘鑰泄露后圆存,及時(shí)更新一般秘鑰叼旋,APP發(fā)一個(gè)新版本,被泄露版本的秘鑰再請求一些核心接口及場景時(shí)沦辙,提示用戶必須更新APP才能使用夫植,這樣就可以防止出現(xiàn)一些大的損失
extension String {
// 生成隨機(jī)秘鑰
static func randomKey: String {
return "時(shí)間版本每個(gè)版本發(fā)布前下發(fā)的秘鑰等綜合組成的變化的秘鑰"
}
// 客戶端的處理
func encodeAESBase64(key: String) -> String {
// 1、對字符串?dāng)?shù)據(jù)轉(zhuǎn)換成Data
guard let data = self.data(using: .utf8) else {
return ""
}
// 2怕轿、對data進(jìn)行AES加密
let encodeData = `使用AES進(jìn)行加密`
// 3偷崩、將aes加密后的數(shù)據(jù)轉(zhuǎn)換成base64字符串
let base64Str = encodeData?.base64EncodedString()
return base64Str ?? ""
}
// 模擬服務(wù)端收到后的處理
func decodeAESBase64(key: String) -> String {
// 1、對數(shù)據(jù)先進(jìn)行base64還原成data
guard let data = Data(base64Encoded: self) else {
return ""
}
// 2撞羽、對數(shù)據(jù)進(jìn)行AES解密
guard let decodeData = `AES解密` else {
return ""
}
// 3阐斜、對解密的數(shù)據(jù)還原成字符串
let decodeStr = String(data: decodeData, encoding: .utf8)
return decodeStr ?? ""
}