無論你是編寫銀行應(yīng)用還是游戲,如果應(yīng)用使用了網(wǎng)絡(luò)嘲更,它就應(yīng)該是安全的筐钟。除了最不重要的數(shù)據(jù)之外,軟件不可能確定用戶的數(shù)據(jù)是否是機(jī)密的赋朦、尷尬的篓冲、還是危險的〕韬澹看似無關(guān)緊要的信息壹将,其實很可能泄密。
由于這些原因琳拨,要始終假設(shè)應(yīng)用遇到的每個數(shù)據(jù)瞭恰,都可能包含銀行賬號或密碼,需要得到保護(hù)狱庇。
應(yīng)用可能遭遇到的攻擊包括:
- 窺探——第三方嗅探到傳輸中的應(yīng)用數(shù)據(jù)的攻擊惊畏。
- 中間人攻擊——第三方將自己的計算機(jī)插入到應(yīng)用和服務(wù)器之間。中間人攻擊包括:
- 窺探和網(wǎng)絡(luò)誘騙——創(chuàng)建偽裝成合法服務(wù)器的假服務(wù)器密任。
- 篡改——修改服務(wù)器和應(yīng)用之間的數(shù)據(jù)颜启。
- 會話劫持——捕獲認(rèn)證信息,將其作用于用戶浪讳。
- 注射攻擊——該攻擊使用特定的騙術(shù)數(shù)據(jù)缰盏,它能導(dǎo)致客戶端或服務(wù)器端軟件執(zhí)行未被檢查的命令。這通常發(fā)生在程序與腳本交互的時候,例如shell或者SQL數(shù)據(jù)庫服務(wù)器口猜。
- 緩存溢出以及數(shù)字溢出——該攻擊使用特定的欺騙數(shù)據(jù)负溪,能導(dǎo)致應(yīng)用在它的地址空間的某些部分讀或?qū)懀欢@些部分济炎,是不應(yīng)該隨意執(zhí)行代碼川抡,或泄露隱私信息,或兩者都不允許的须尚。
本章解釋的是如何防范窺探和中間人攻擊崖堤。想要了解更多關(guān)于注射攻擊、緩存溢出耐床,以及其他軟件安全方面的內(nèi)容密幔,請閱讀Secure Coding Guide。
啟用TLS或SSL
傳輸層安全(Transport Layer Security撩轰, TLS)協(xié)議為基于socket通信提供數(shù)據(jù)加密胯甩,以及服務(wù)器和客戶端的認(rèn)證,來防范窺探攻擊堪嫂。
OS X和iOS也提供對安全socket層(Secure Socket Layer蜡豹,SSL)的支持。因為TLS是SSL的繼任者溉苛。如果兩個協(xié)議都支持镜廉,OS X和iOS在默認(rèn)情況下會使用TLS。
注意:TLS和SSL的設(shè)計主要針對于客戶-服務(wù)器模式愚战。所以在點對點環(huán)境下使用這些協(xié)議很難確保安全通信娇唯。
安全連接到URL
通過TLS連接到URL很輕松。當(dāng)你創(chuàng)建NSURLRequest對象以提供給initWithRequest:delegate:方法時寂玲,指定的https而不是http作為URL的方案塔插。在沒有額外配置的情況下,這個連接自動使用了TLS拓哟。
使用流數(shù)據(jù)的安全連接
你可以通過調(diào)用NSStream對象的setProperty:forKey:方法來使用TLS想许。指定NSStreamSocketSecurityLevelNegotiatedSSL 作為property參數(shù),指定NSStreamSocketSecurityLevelKey作為key參數(shù)断序。如果你需要解決兼容性錯誤流纹,你還可以指定更多特定的協(xié)議,例如NSStreamSocketSecurityLevelTLSv1违诗。
使用BSD Socket的安全連接
當(dāng)進(jìn)行安全連接時漱凝,如有可能,你應(yīng)該使用NSStream(如上一節(jié)所述)而不是直接使用socket诸迟。但是茸炒,如果你必須使用直接BSD socket愕乎,你必須實現(xiàn)SSL或TLS來自己進(jìn)行加密和解密”诠基于你平臺感论,有兩種方式可以做到這一點:
- 在OS X中,或在iOS 5及更高版本中紊册,你可以使用Security框架中的安全傳輸(Secure Transport)API來處理你的SSL和TLS握手交換笛粘、加密、以及解密湿硝。更多詳情參見Secure Transport Reference。
- 在iOS或OS X中润努,你可以下載開源的SSL或TLS實現(xiàn)关斜,例如OpenSSL,并把該庫(或者一部分)的變異副本包含到你的應(yīng)用程序束中(或者和你的非綁定程序在一起)铺浇。確保遵守你可能使用的第三方庫的許可條款痢畜。
注意:雖然OpenSSL庫的一個版本已經(jīng)作為OS X的一部分被包含,但OpenSSL庫不保證不同版本的OpenSSL二進(jìn)制兼容鳍侣。因此丁稀,在OS X v 10.7開始,不在支持連接到OpenSSL的內(nèi)置副本倚聚。如果你想使用OpenSSL线衫,提供庫的你自己的副本,以便你精確地控制程序連接的OpenSSL版本惑折。
在OS X中使用其他安全協(xié)議
除了默認(rèn)的TLS安全傳輸實現(xiàn)授账,下面的網(wǎng)絡(luò)安全協(xié)議在OS X中也是可用的:
- Kerberos協(xié)議可以通過Kerberos框架使用。這個協(xié)議提供通過網(wǎng)絡(luò)單點登錄認(rèn)證的支持惨驶。更多信息白热,閱讀read Security Overview 和 Authentication, Authorization, and Permissions Guide.
- 安全外殼(Secure Shell,SSH)協(xié)議粗卜。這個協(xié)議通常使用于終端應(yīng)用登錄遠(yuǎn)程主機(jī)水孩。更多信息參見ssh介陶。
- TLS的OpenSSL實現(xiàn),但是由于二進(jìn)制兼容性原因,OS X v10.7之預(yù)裝的OpenSSL庫被棄用衙猪。如果你需要OpenSSL,則提供該庫的你自己的副本苇羡,并將其靜態(tài)連接到你的應(yīng)用形导。
常見錯誤
在編寫安全網(wǎng)絡(luò)代碼的時候,有一些開發(fā)者常犯的錯誤砌些。本部分提供為避免其中幾個錯誤的建議呜投。
謹(jǐn)慎對待你相信的服務(wù)器
如果應(yīng)用和服務(wù)器傳輸有潛在機(jī)密的數(shù)據(jù)加匈,要確保它對服務(wù)器的認(rèn)證,以保證它沒有被欺騙仑荐。確認(rèn)你的服務(wù)器認(rèn)證當(dāng)前的客戶端雕拼,來避免把數(shù)據(jù)提供給錯誤的用戶。此外粘招,確保連接使用合適的加密方式進(jìn)行了加密啥寇。
同樣的,請確保僅在必要的時候存儲數(shù)據(jù)洒扎,并以執(zhí)行任務(wù)所需的最小量來提供數(shù)據(jù)辑甜。例如,為了最大限度的提高用戶個人信息的隱私性袍冷,你可以將網(wǎng)絡(luò)服務(wù)器的數(shù)據(jù)庫放在獨立的服務(wù)器上磷醋,配置為僅從你的網(wǎng)絡(luò)服務(wù)器上接收SQL請求,顯示它和整個網(wǎng)絡(luò)的連接胡诗。換句話所邓线,使用了適當(dāng)?shù)臋?quán)限分離。
更多信息煌恢,請閱讀Secure Coding Guide中的Designing Secure Helpers and Daemons骇陈。
謹(jǐn)慎對待你相信的數(shù)據(jù)
每個應(yīng)用到處在被惡意內(nèi)容攻擊的危險之中。尤其是在應(yīng)用從不受信任的服務(wù)器獲取數(shù)據(jù)瑰抵,或從信任的服務(wù)器獲取不信任數(shù)據(jù)的時候(例如論壇帖子)你雌。
為了防止這樣的攻擊,應(yīng)用應(yīng)該小心的檢查所有來自網(wǎng)絡(luò)或磁盤(因為用戶或許已經(jīng)下載了數(shù)據(jù))的數(shù)據(jù)二汛。如果數(shù)據(jù)以某種方式表現(xiàn)出了惡意匪蝙,不要像處理正常數(shù)據(jù)那樣處理它。
更多信息习贫,參見Secure Coding Guide中的Validating Input and Interprocess Communication
要知道千里之堤潰于蟻穴
始終采取措施確保應(yīng)用在網(wǎng)絡(luò)中的內(nèi)容保持私有逛球。雖然某些信息本身看上去是無用的,但是一個老練的攻擊者可以把該信息和其他信息進(jìn)行結(jié)合苫昌,從而可能發(fā)現(xiàn)比單條信息本身有用的多的隱私事件——該過程就是數(shù)據(jù)挖掘颤绕。
例如,如果某人想要進(jìn)入你的房間祟身,在周六晚上在圖書館發(fā)一個帖子可能是無用的奥务,但是連續(xù)幾個周六在相同的時間在圖書館發(fā)帖子就可能不是無用的了,因為它們表明了你的習(xí)慣袜硫。
數(shù)據(jù)甚至不需要都是針對同一件事也可以造成傷害氯葬。知道某人喜歡看特定的電視節(jié)目可能無害,但是一個人的喜好婉陷、購買的物品帚称、以及交往的朋友組成的完整側(cè)寫官研,可能可以和一個人的隱私有強(qiáng)關(guān)聯(lián)性,例如宗教和性取向闯睹。一個令人印象深刻的例子(也可能不是事實)戏羽,說連鎖零售企業(yè)承認(rèn),它們通過一個女孩的購買決定斷定她已經(jīng)懷孕楼吃,而女孩的父親此時還尚不知情始花。
身份信息泄露特別成問題。如果你的應(yīng)用泄露了手機(jī)號孩锡,其他應(yīng)用可能泄露郵政地址等等酷宵。當(dāng)攻擊者搜集到受害者足夠信息的時候,他就可以使用社交工程技術(shù)來說服第三方給他更多信息躬窜,從而導(dǎo)致信息收集的反饋循環(huán)浇垦,造成毀滅性后果。
因此斩披,應(yīng)用在任何時候進(jìn)行加密通信是非常重要的,針對所有連接讹俊,除非這樣做不可行垦沉。你永遠(yuǎn)不知道此時看起來無害的信息,在和別的看似無害的信息結(jié)合之后仍劈,就有可能發(fā)酵為危險或傷害厕倍。
正確的安裝證書
當(dāng)使用TLS或SSL連接服務(wù)器的時候,如果應(yīng)用得到一個錯誤贩疙,表示簽發(fā)了你的證書的認(rèn)證機(jī)構(gòu)是未知的讹弯,假設(shè)你從有信譽(yù)的認(rèn)證機(jī)構(gòu)獲取的證書,那么者幾乎就是意味著你的證書鏈丟失或不完整这溅。
當(dāng)你的服務(wù)器接收到一個通過TLS或SSL加密的連接组民,它會提供兩樣?xùn)|西:你的服務(wù)器的SSL證書,以及完整的SSL證書鏈悲靴,從服務(wù)器的證書開始臭胜,到一個被信任的錨證書簽名的證書止,這個錨證書是被操作系統(tǒng)識別的癞尚。如果證書鏈中有證書丟失耸三,你將得到一個錯誤,因為鏈中的較早的證書無法被后面的證書驗證浇揩。
想要查看你的服務(wù)器到底發(fā)送了什么仪壮,在終端中輸入以下命令(將www.example.com替換成你的真實域名)并按下回車鍵:
openssl s_client -showcerts -connect www.example.com:443
當(dāng)你輸入這個命令時,你應(yīng)該可以看到你的服務(wù)器證書胳徽,然后時一系列中間證書积锅。如果你沒有得到爽彤,檢查你的服務(wù)器配置。想要獲取正確的證書以便放置到你的服務(wù)器證書鏈中乏沸,請與提供服務(wù)器SSL證書的認(rèn)證機(jī)構(gòu)聯(lián)系淫茵。
永遠(yuǎn)不要禁用證書鏈驗證(除非你自己驗證)
禁止鏈驗證消除了你使用安全連接可能得到的任何好處。所得到的連接不比使用沒有加密的HTTP發(fā)送請求更安全蹬跃,因為它沒有提供防止假服務(wù)器欺騙的保護(hù)匙瘪。
如果你使用受信任的認(rèn)證機(jī)構(gòu)的服務(wù)器證書,確保你的證書正確的被安裝(查看上一部分)蝶缀。
如果你臨時使用自簽名的證書丹喻,你應(yīng)該把它們添加到你的測試機(jī)器的可信任錨列表中。在OS X中翁都,你可以使用Keychain Access(鑰匙串訪問)實用工具應(yīng)用做到這一點碍论。在iOS中,你可以在程序中使用SecTrustCopyAnchorCertificates, SecTrustCreateWithCertificates, 和 SecTrustSetAnchorCertificates函數(shù)柄慰。
如果你需要特別允許的單獨的自簽名證書鳍悠,或為不同(特定)主機(jī)的簽名證書,你可以通過閱讀Overriding TLS Chain Validation Correctly來了解這樣做的安全方式坐搔。