眾所周知APPLE的iOS是封閉的见妒,每個(gè)app有著沙盒路徑,正規(guī)發(fā)布途徑也只有唯一的APPStore, 但是市場(chǎng)上越獄手機(jī)和強(qiáng)大的抓包工具依然時(shí)時(shí)刻刻威脅著App 的安全郊供,而且隨著項(xiàng)目慢慢積累用戶峡碉,用戶的隱私和數(shù)據(jù)安全越來(lái)越重要。要知道危險(xiǎn)遍布于開(kāi)發(fā)的各個(gè)階段驮审,而且對(duì)安全的重視程度也間接體現(xiàn)了一個(gè)開(kāi)發(fā)者的能力和意識(shí)鲫寄。本文針對(duì)項(xiàng)目數(shù)據(jù)傳輸和本地存儲(chǔ)著兩塊,將開(kāi)發(fā)過(guò)程中涉及到和安全相關(guān)的問(wèn)題都記錄下來(lái)疯淫,作為積累地来。
數(shù)據(jù)安全傳輸
1. 關(guān)鍵字段加密
在iOS開(kāi)發(fā)過(guò)程中,抓包是常見(jiàn)的必備技能之一峡竣。我們可以使用抓包利器Charles 或者使用 Fidder 進(jìn)行抓包靠抑,在應(yīng)用進(jìn)行發(fā)送請(qǐng)求的時(shí)候,如果沒(méi)有對(duì)數(shù)據(jù)和關(guān)鍵信息進(jìn)行加密的話适掰,那么恭喜你颂碧,你的數(shù)據(jù)在網(wǎng)上裸奔了,與此同時(shí)要是有人想獲取你的隱私簡(jiǎn)直再容易不過(guò)了类浪,而且還可以篡改你的請(qǐng)求载城,讓你原本準(zhǔn)備充值 1 元的賬戶,生生變成 100元费就,甚至更多诉瓦。
所以我們需要在請(qǐng)求數(shù)據(jù)或者服務(wù)端返回?cái)?shù)據(jù)的時(shí)候需要進(jìn)行數(shù)據(jù)的加密,目前可逆的加密方法主要有:
RSA - 非對(duì)稱加密
DES - 對(duì)稱加密
AES - 對(duì)稱加密
使用 RSA 加密是最安全的力细,但加解密的時(shí)候也相應(yīng)需要較多的時(shí)間睬澡,所以建議一般加密的接口敏感數(shù)據(jù)使用 DES 或者 AES 就足夠了。
算法實(shí)現(xiàn):RSA_DES_AES加密算法 demo
2. HTTPS 協(xié)議傳輸
自蘋(píng)果宣布2017年1月1日開(kāi)始強(qiáng)制使用https以來(lái)眠蚂,htpps慢慢成為大家討論的對(duì)象之一煞聪,不是說(shuō)此前https沒(méi)有出現(xiàn),只是這一決策讓得開(kāi)發(fā)者始料未及逝慧, 雖然在2016年底昔脯,蘋(píng)果突然宣布無(wú)限期推遲這個(gè)計(jì)劃,不過(guò)隨著網(wǎng)絡(luò)世界的日益發(fā)達(dá)笛臣,將自己開(kāi)發(fā)的產(chǎn)品從 http 升級(jí)到 https 已經(jīng)是勢(shì)在必行了云稚, 最近在項(xiàng)目中已經(jīng)將 https 應(yīng)用其中,在這里記錄下來(lái)沈堡,以幫助其他開(kāi)發(fā)者快速接入 https 静陈。
詳情請(qǐng)見(jiàn): iOS https 協(xié)議 配置
本地存儲(chǔ)加密
1. 配置文件
為了存儲(chǔ)必要的數(shù)據(jù)在本地,一般情況下使用NSUserDefaults 或者使用數(shù)據(jù)庫(kù)的方式踱蛀。由于在越獄的手機(jī)上窿给,用戶可以訪問(wèn)到該項(xiàng)目的私有文件夾贵白,并且可以拿到 plist 和 db 文件,那么如果明文存儲(chǔ)敏感數(shù)據(jù)的話崩泡,那么就可以輕易獲取禁荒,危害用戶的信息隱私,解決的辦法在于角撞,需要將這些信息進(jìn)行加密之后再存儲(chǔ)呛伴,雖然這樣不能完全防止被破解,但是這樣提高了黑客的破解代價(jià)谒所。
具體的加密可以參照關(guān)鍵字段加密介紹的 RSA热康,DES 和 AES 加密算法。
最好不要使用 Base64 這種簡(jiǎn)單的加密和 md5 這種不可逆的加密劣领,當(dāng)然使用 DES 和 AES 也不是完全安全的姐军,只要黑客對(duì)你的源碼進(jìn)行解析,發(fā)現(xiàn)了加密的公鑰尖淘,依然可以破解你的信息奕锌,所以最好的方法是定期更換公鑰,或者由服務(wù)器分配公鑰村生。
2. NSLog 打印內(nèi)容緩存
為了清晰的看到接口返回的數(shù)據(jù)惊暴,或者為了定位每一步調(diào)用,相關(guān)參數(shù)的變化趁桃,有很多程序員會(huì)使用 NSLog 將數(shù)據(jù)和參數(shù)的值進(jìn)行打印辽话,而且一些第三方框架也會(huì)進(jìn)行數(shù)據(jù)打印,這些數(shù)據(jù)在程序運(yùn)行之后會(huì)在沙盒內(nèi)的 /Library/Caches 下進(jìn)行緩存卫病。建議有打印數(shù)據(jù)需求的開(kāi)發(fā)者將 NSLog 進(jìn)行封裝:
//------------------------打印日志-----------------------------
//DEBUG 模式下打印日志,當(dāng)前行
#ifdef DEBUG
# define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#else
# define DLog(...)
#endif
#ifdef DEBUG
# define QXDLog(fmt, ...) NSLog((@"-------------- \n %s [Line %d] \n------------" fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
#define QXDAFNErrorLog(error) NSLog((@"-------------- \n %s [Line %d] \n \n %@-------------\n"), __PRETTY_FUNCTION__, __LINE__, [[NSString alloc] initWithData:error.userInfo[@"com.alamofire.serialization.response.error.data"] encoding:NSUTF8StringEncoding]);
#else
# define QXDLog(...)
# define QXDAFNErrorLog(error)
#endif
然后一般的第三方框架都會(huì)有 Log 輸出等級(jí)的設(shè)置油啤,在測(cè)試完成之后,可以將其設(shè)置為不輸出 Log蟀苛,保證安全村砂。
3. SQLite數(shù)據(jù)庫(kù)文件
打開(kāi)程序目錄/Library/Caches/項(xiàng)目bundle ID/下的cache.db文件, 會(huì)發(fā)現(xiàn)這個(gè) db 文件對(duì)每個(gè)接口的請(qǐng)求返回?cái)?shù)據(jù)進(jìn)行了存儲(chǔ),當(dāng)然包括以下敏感的數(shù)據(jù)屹逛,例如:用戶登錄完成之后后臺(tái)返回的用戶信息數(shù)據(jù),用戶 Token ....這些信息是由 AFNetworking 這個(gè)框架進(jìn)行緩存的汛骂。
而這些緩存對(duì)我們都是沒(méi)有用的罕模,這個(gè)時(shí)候可以使用限制程序緩存的方式,讓這些緩存消失:
// 清除本地?cái)?shù)據(jù)請(qǐng)求緩存
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:0];
[NSURLCache setSharedURLCache:sharedCache];