App安全之網絡傳輸安全

App安全之網絡傳輸安全

移動端App安全如果按CS結構來劃分的話,主要涉及客戶端本身數據安全,Client到Server網絡傳輸的安全,客戶端本身安全又包括代碼安全和數據存儲安全。所以當我們談論App安全問題的時候一般來說在以下三類範疇當中。

  • App代碼安全,包括代碼混淆,加密或者app加殼。
  • App數據存儲安全,主要指在磁盤做數據持久化的時候所做的加密。
  • App網絡傳輸安全,指對數據從客戶端傳輸到Server中間過程的加密,防止網絡世界當中其他節點對數據的竊聽。

這一篇我們先聊下網絡傳輸的安全。

安全相關的基礎概念

網絡安全相關的概念非常之多,要在廣度和深度上都有所造詣很困難。但如果只是站在保障App通信基本安全這個維度上,做到合理使用安全算法,比大部分人所預期的都要簡單很多。以下這些基礎概念是必備知識:

  • 對稱加密算法,代表算法AES
  • 非對稱加密算法,代表算法RSA,ECC
  • 電子簽名,用於確認消息發送方的身份
  • 消息摘要生成算法,MD5,SHA,用於檢測消息是否被第三方修改過

怎麼樣算安全?

安全問題說白了是信任問題,談到信任一定要有一個可被信任的實體。假設某天A收到了一條“Message”,如果這個消息確實是來自B,消息就可以被信任,那麼B就這安全問題當中可被信任的實體。

對於A來說只要滿足三點就說明收到“Message”是安全的:

  • Message有B的電子簽名,表明消息確實是來自B。
  • Message沒有被篡改過。
  • Message被某種加密算法加密過,只有A和B知道如何解密。

A和B的交談如果放到網絡世界當中,就是典型的Client-Server模式。和現實世界當中聊天不同的是,A和B所說的任何話都可以輕而易舉的被其他人聽到,隔牆隨處有耳。

怎麼去保證App網絡傳輸的安全?

爲了保證傳輸數據的安全,需要使用加密算法。在決定什麼樣的業務場景使用什麼樣的加密算法之前,先要了解我們的工具箱裏有哪些可用工具。加密算法的工具箱裏其實就兩種工具:“對稱”加密算法和“非對稱”加密算法。清楚這兩個分類是合理設計加密算法使用場景的大前提,兩個分類裏我們各挑選一個代表算法來研究,“對稱”加密挑選AES,“非對稱”加密選擇RSA。瞭解AES和RSA之後我們再針對一些特定業務場景設計安全模型。

對稱加密之AES

要深入瞭解像AES這種加密算法,對大部分初學的同學來說可能有些費時費力,但對算法掌握可以是個循序漸進的過程。簡單來說可以分爲以下幾個階段:

階段一: 在AES誕生之前(1975年之前),早起的加密算法十分簡單,是一種類似“暗號”的機制。通信的雙方通過事先約定一種“加密機制”對明文進行處理,只要“加密機制”不被泄漏,信息就算安全。後來無數的經驗表明算法總是會被第三方得知,對算法本身進行保密管理也不方便。

階段二: 到上世紀70年代,公衆和政府意識到加密算法的重要性,由美國政府機構NBS牽頭組織業界專家設計了DES算法。DES算法本身公開,但算法的安全全依賴於一個密鑰。後來DES統治加密算法長達二十多年。不過DES從誕生到逐步退出歷史舞臺,一直都伴隨着陰謀的論調。DES原本是由IBM提出,針對已有算法Lucifer改造而成,但DES制定的過程一直都有美國另一政府機構NSA的影子。

DES的兩大特點是短密鑰(short key)和結構複雜的s-box。有研究表明,是NSA當時勸說IMB短密鑰足夠安全,而且NSA也直接參與了s-box的設計。後來就一直有傳言說NSA似乎有辦法能輕易破解DES加密後的祕文。

到1990年,劇情出現反轉。第三方獨立研究者Eli Biham和Adi Shamir發佈了破解塊加密方式的通用破解方法differential cryptanalysis。出人意料的是按照NSA建議設計的s-box對這種破解方法有更好的免疫性,NSA的參與似乎更加提高了DES的安全性。

到1994年,劇情進一步昇華。公開文件披露,早在1974年IBM的研究者就已經發現了differential cryptanalysis這種破解方式,不過這項研究被NSA禁止公開,理由是會威脅到國家安全,對,就是現在美劇裏經常提到的national security。不僅如此,NSA還針對DES做了一些改造加強安全性。至此,NSA已經全身都掛滿了節操,被業界質疑忍辱負重二十多年一聲沒吭,比24小時男主角Jack Bauer形象更加高大光輝。

階段三: 後來陸陸續續有一些針對DES破解的攻防戰,DES最終演化成Triple DES的形態,不過在性能上已經出現明顯問題,催生了今天對稱加密的王者算法AES。AES在安全性,實現難度,運算性能上都有更好的表現。在全面瞭解AES之前,首先明確下好的加密算法必須符合哪些條件,這些條件是經過數十年加密破解攻防戰所總結出來的。

  • 條件一,Confusion。對原文以最小的粒度(按字節)進行混淆生成祕文。最簡單的confusion可以是A+3=D.
  • 條件二,Deffusion。對原文所包含的位置信息進行打亂排布,比如將第一個字節與第四個字節的位置對換.
  • 條件三,Secret Key。最終的祕文與Secret Key相關,只要持有Secret Key就可以對數據解密,將安全性的管理歸於一個密鑰的管理。

AES也是屬於Cipher Block的一種,對於數據的加密都是已block爲單位進行處理。針對需要加密的數據AES會先把數據分成一個個的block,每個block爲16字節,可以排布成4x4的表格(又名矩陣)。如下圖所示:

如果最後一塊不足16字節,用0補齊(padding)。後續的加密行爲都是以block爲單位進行處理,這個處理過程必須滿足上述所說三個條件。加密的流程如下圖:

每一個block都會被單獨依次處理,橙色方框表示加密的過程,這個過程包括兩個方面,一方面是block本身數據的運算處理,二是與round key(也就是我們所說的對稱加密算法密鑰)進行運算處理。流程示意圖如下:

每一個block會依次經過Confusion(條件一),Difussion(條件二),Mix Data(可以看作再一次的Confusion)。最後一步是和我們的round key進行位運算得到最後的block祕文,這樣一個完整的來回稱爲一個round,重複10次round就完成了block加密,當然每個round當中所使用的round key也會發生變化,以保證每次block加密所使用的key都不同。

針對每個block都重複上述處理過程就完成了AES加密過程,是不是so easy。當然這是被我高度抽象簡化後的流程示意圖,當中每一步都有很多的細節可以深入。密鑰越長,每個block處理的round次數越多,AES就越安全,不過安全性和計算性能不可兼得,一般來說,我們使用128bit的Key就可以保證算法的安全性了。對了,解密的過程就是把上面加密的過程反過來做一遍。。

階段四: 明白了AES的流程,還需要了解正確的使用姿勢。AES有兩個經典的使用姿勢,ECB模式和CBC模式。ECB模式可以用下圖表示:

ECB模式很簡單,就是針對每一個block單獨進行AES運算,每個block的處理結果之間沒有任何關係。使用這種方式單個block都是安全的,但對包含大量block的數據來說,沒有能夠隱藏data pattern,因爲相同的原文會產生相同的祕文,這對圖片文件來說比較致命:

相同的色塊產生相同的祕文,這樣相同顏色在圖片當中出現的規律就和原始數據一樣一目瞭然。

CBC模式針對ECB模式的缺陷做了處理,使得每個block的AES運算結果都依賴於之前的block祕文。如下圖所示:

每一個block在加密之前都會與上個block產生的祕文進行抑或運算,這樣相同的數據也會產生不同的祕文,data pattern得以隱藏。第一個block沒有刻可以或處理的祕文,就傳入一個IV(初始化向量)。很明顯,IV不同,AES運算的結果也不同。

非對稱加密之RSA

對稱加密的安全性全繫於加密密鑰的管理,在非對稱加密算法出現之前,如何動態的協商密鑰一直是個難題,大部分的應用場景都是採用通信雙方通過其他手段預先交流密鑰的方式。一旦密鑰泄漏,就會導致嚴重的安全事故。直到1976年Diffie Hellman算法出現解決了密鑰協商的問題,1977年RSA誕生同時提供了密鑰協商方案和電子簽名方案。

RSA的使用已經相當廣泛,也有很多優秀的教程解釋其原理,推薦其中一篇

關於RSA這種非對稱加密算法,在App的使用當中,需要明白其主要作用有2個:

  • 信息加密:通信雙方可以在公開的網絡環境下,“安全”的商量對稱加密算法所使用的密鑰。
  • 電子簽名:爲了防止中間人攻擊,通信雙方在商量密鑰之前可以通過簽名算法確認對方的身份。

非對稱加密算法本身是一種加密算法,但由於RSA本身加解密的性能在現在的計算機硬件條件下存在一定瓶頸,同時對加密數據的“安全長度”也有限制,被加密數據的長度一般要求不超過公鑰的長度。所以RSA更多的是被用來商量一個密鑰,如果密鑰是安全的,那麼後續的通信都可以使用上面提到的AES來完成,AES在性能上不存在瓶頸。

RSA算法最經典也是最廣泛的應用場景是HTTPS,HTTPS的安全握手流程完整的闡釋了“加密”和“簽名”這兩個概念。推薦一篇文章詳細的分析HTTPS的握手流程。

RSA有另一個競爭者ECC,ECC現在使用也越來越廣泛。二者在安全性上都不存在問題。不過ECC額外的優勢,公鑰私鑰的生成速度快於RSA,在需要大量生產密鑰對的業務場景下ECC會是更好的選擇。ECC的最短安全公鑰也比RSA要短的多,224bits的ECC公鑰就已經足夠安全,而同等級別的RSA公鑰需要長達2048bits。RSA由於實現簡單,出現較早,可以預見在很長一段時間內都將和ECC共存。

App網絡應用場景

現在絕大部分的App都在使用http和https,少部分會有自己的tcp長連接通道,更少部分的app搭配udp通道或者類似QUIC這種reliable UDP協議來提升體驗。不管是什麼協議,只要涉及客戶端和服務器的通信,就必然要實現類似https安全握手的流程,部分或者全部,開發者總是在性能和安全性之間取捨。有實力的大廠可以魚與熊掌兼得,初創型企業往往會避開性能優化,直接跳過安全問題。

使用http,不做任何加密相當於裸奔,初級工程師都可以輕易窺探你全部的業務數據。

使用http,但所有的流量都通過預埋在客戶端的key進行AES加密,流量基本安全,不過一旦客戶端代碼被反編譯竊取key,又會回到裸奔狀態。

使用http,但AES使用的key通過客戶端以GUID的方式臨時生成,但爲了保證key能安全的送達服務器,勢必要使用服務器的公鑰進行加密,所以要預埋服務器證書,又涉及到證書過期更新機制。而且無法動態協商使用的對稱加密算法,安全性還是有暇疵。

所以要做到真正的安全,最後還是會迴歸到https的流程上來,https在身份驗證,密鑰協商,解密算法選擇,證書更新等方面都已經做了最合適的選擇。

對於App開發者來說,到底選擇什麼樣的安全策略,是在全盤瞭解現有安全模型的前提下,在投入,產出,風險三者之間去平衡而做出最優的選擇。

App網絡安全實戰

在App安全上的投入再多也不會過,不過安全問題上所投入的開發資源應該根據開發團隊技術積累,產品發佈deadline,用戶規模及產品關注度等綜合因素考量。結合這些因素我把App分爲三類,各類App對安全級別的要求不同,投入產出也不同。

第一類,作坊式創業App

這些年伴隨着移動互聯網的創業潮,各式各樣的app出現在用戶的手機端。對於創業初期的團隊來說,能把業務模型儘快實現上線當然是重中之重。但很多創業團隊在安全上的投入幾乎爲零,所導致的安全問題比想象中的要嚴重。我見過不少使用http明文傳輸用戶名密碼的app,其中甚至包括一些知名傳統企業。其實只要照顧到一些基礎方面就能過濾掉大部分的安全漏洞了。這裏提供一些小tip供創業初期團隊參考:

Tip 1:儘量使用https

https可以過濾掉大部分的安全問題。https在證書申請,服務器配置,性能優化,客戶端配置上都需要投入精力,所以缺乏安全意識的開發人員容易跳過https,或者拖到以後遇到問題再優化。https除了性能優化麻煩一些以外其他都比想象中的簡單,如果沒精力優化性能,至少在註冊登錄模塊需要啓用https,這部分業務對性能要求比較低。

Tip 2:不要傳輸密碼

不知道現在還有多少app後臺是明文存儲密碼的。無論客戶端,server還是網絡傳輸都要避免明文密碼,要使用hash值。客戶端不要做任何密碼相關的存儲,hash值也不行。存儲token進行下一次的認證,而且token需要設置有效期,使用refresh token去申請新的token。

Tip 3:Post並不比Get安全

事實上,Post和Get一樣不安全,都是明文。參數放在QueryString或者Body沒任何安全上的差別。在Http的環境下,使用Post或者Get都需要做加密和簽名處理。

Tip 4:不要使用301跳轉

301跳轉很容易被Http劫持攻擊。移動端http使用301比桌面端更危險,用戶看不到瀏覽器地址,無法察覺到被重定向到了其他地址。如果一定要使用,確保跳轉發生在https的環境下,而且https做了證書綁定校驗。

Tip 5:http請求都帶上MAC

所有客戶端發出的請求,無論是查詢還是寫操作,都帶上MAC(Message Authentication Code)。MAC不但能保證請求沒有被篡改(Integrity),還能保證請求確實來自你的合法客戶端(Signing)。當然前提是你客戶端的key沒有被泄漏,如何保證客戶端key的安全是另一個話題。MAC值的計算可以簡單的處理爲hash(request params+key)。帶上MAC之後,服務器就可以過濾掉絕大部分的非法請求。MAC雖然帶有簽名的功能,和RSA證書的電子簽名方式卻不一樣,原因是MAC簽名和簽名驗證使用的是同一個key,而RSA是使用私鑰簽名,公鑰驗證,MAC的簽名並不具備法律效應。

Tip 6:http請求使用臨時密鑰

高延遲的網絡環境下,不經優化https的體驗確實會明顯不如http。在不具備https條件或對網絡性能要求較高且缺乏https優化經驗的場景下,http的流量也應該使用AES進行加密。AES的密鑰可以由客戶端來臨時生成,不過這個臨時的AES key需要使用服務器的公鑰進行加密,確保只有自己的服務器才能解開這個請求的信息,當然服務器的response也需要使用同樣的AES key進行加密。由於http的應用場景都是由客戶端發起,服務器響應,所以這種由客戶端單方生成密鑰的方式可以一定程度上便捷的保證通信安全。

Tip 7:AES使用CBC模式

不要使用ECB模式,原因前面已經分析過,記得設置初始化向量,每個block加密之前要和上個block的祕文進行運算。

第二類,正規軍App

All Traffic HTTPS

全站使用HTTPS,而且是強制使用。baidu到今天(2016.04.13)還沒有強制使用HTTPS。所有的流量都應該在HTTPS上產生,沒有人可以決定哪些流量是可以不用考慮安全問題的。如果自建長連接使用tcp,udp或者其他網絡協議,也應該實現類似HTTPS的密鑰協商流程。

Certificate Pinning

RSA的簽名機制雖然看着安全,一旦出現上游證書頒發機構私鑰泄漏,或者簽名流程發現漏洞等情況,中間人攻擊還是會導致數據被第三方破解甚至被釣魚。Certificate Pinning是一種與服務器證書強綁定的機制,要麼綁定證書本身,需要證書更新機制配合加強安全性,要麼使用私鑰綁定,這樣更新證書的時候只要保證私鑰不變即可。現在流行的HTTP framework,iOS端如AFNetworking,Android端如OKHttp都支持Certificate Pinning。

Perfect Forward Secrecy

很多人會覺得非對稱加密算法足夠安全,只要使用了RSA或者AES,加密過後的數據就認爲安全。但沒有絕對的安全,無論是RSA或者AES算法本身都有可能在未來某一天被破解,正如當年的DES,甚至有傳言NSA正如當年掌握了differential cryptanalysis一樣,現在已經獲取了某種方法來破解當前互聯網當中的部分網絡流量,至於到底是RSA還是AES就不得而知了。

未來計算機的計算能力是個未知數,或許某一天brute force能夠暴力破解的密鑰長度會遠超128bits(現階段上限應該在80bits)。

2014年1月3日,美國國家安全局(NSA)正在研發一款用於破解加密技術的量子計算機,希望破解幾乎所有類型的加密技術。

即使算法本身沒有被破解,密鑰也有可能被泄漏,技術上的原因或者政策上的因素都可能導致RSA或者ECC的私鑰被泄漏。所以儘可能針對不同的session使用不同的key能夠使的我們的數據更佳安全。

Forward Secrecy就是爲了避免某個私鑰的泄漏或者被破解而導致歷史數據一起泄漏。現在google的https配置所使用的是TLS_ECDHE_RSA算法,每次對稱密鑰的協商都是使用ECC生成臨時的公鑰私鑰對(之前提到過ECC在快速生成密鑰對上有優勢),身份驗證使用RSA算法進行簽名。

每天跟蹤信息安全動態

安全的攻防戰不會有窮盡的一天,算法的更替會伴隨着人類對知識的無盡渴望延綿至不可預知的未來。AES說不定哪天被破解了,openSSL可能又出現新的漏洞了,google又提倡新的安全模型了,NSA的量子計算機說不準已經在悄悄解密google的流量了,每天跟蹤八卦最新業界動態纔是碼農避免因bug而背黑鍋的不二法寶。

第三類,帶節操正規軍App

現在互聯網早已滲入每個人的平常生活當中,當我們的行爲越來越多的遷移到互聯網這個媒介當中之後,行爲本身及所產生的關聯數據都將被滴水不漏的記錄起來,特別是在大數據研究興起的當下,服務提供商總是希望儘可能多的記錄用戶所有的行爲數據。每個互聯網產品的使用者都成了樣本,你的購物記錄,商品瀏覽歷史,搜索引擎搜索記錄,打車記錄,租房記錄,股票記錄,甚至聊天記錄等等都是樣本,毫不誇張的說,如果將淘寶,微信,支付寶,快滴,美團等等高頻次產品數據統一分析,基本上可以將你的身高,性別,年齡,三維,家庭住址,戀愛史,家庭成員,甚至是個人喜好,性格等等完美的呈現出來,其後果遠不是一個騷擾電話帶來的隱私泄漏那麼簡單。

移動互聯網的大部分使用者還不具備強烈的安全意識,當你用手機號作爲登錄id方便記憶的同時,騷擾電話就可能隨時來臨,你在百度輸入租房關鍵字,下一秒中介就已經電話打上門。當你允許app上傳通訊錄匹配可能認識的好友同時,你認識哪些人就變得一清二楚,你p2p借貸未及時歸還時,你的親朋好友第二天就收到了催債電話。我們在享受移動互聯網的便利同時,付出的是個人隱私這種隱形成本。下一次,當我們感嘆新app好用便利的同時,靜思三分鐘,好好想想我們的哪些隱私又被當白菜賣了。

在互聯網受衆的安全意識普遍覺醒之前,只能靠app開發商,服務提供商的節操來保證用戶信息隱私安全。

帶節操的App在打算記錄用戶行爲或者數據之前會考慮下是不是真的有需要,用戶的確會有需要查詢歷史購買記錄,但有多少人會在意自己幾年前花幾個小時瀏覽了杜蕾斯的產品。

服務器作爲數據存儲或者轉發的媒介是不是真的需要了解真實的數據爲何?現在WhatsApp,Telegram都已經支持端到端的加密聊天方式,服務器本身看到的都是祕文,只做祕文轉發處理,帶着這樣的節操設計產品,用戶纔會覺得安全。

WhatsApp的端到端加密安全模型是怎麼樣實現的呢?非常值得學習。

簡單來說是嚴格遵循forward secrecy。每個用戶在註冊成功之後會在服務器存一對永久的Identity Key,一對臨時的Signed Pre Key(Signed Pre Key由Identity Key簽名,每隔一段時間變化一次),n對臨時的One-Time Pre Key(每次建立session消耗一個)。

每次session開始建立的時候使用Identity Key,Signed Pre Key, One Time Key生成Master Secret。Master Secret再通過HKDF算法生成對稱加密使用的Root Key,Chain Key,Message Key。

Forward Secrecy體現在每次sender發送的消息被ack後,都會交換新的臨時ECC Key對,並更新Root Key,Chain Key,Message Key。這樣網絡中的流量即使被第三方緩存起來,而且某一天某個Key Pair的私鑰被破解,也不會對之前的流量產生安全影響。ECC Key對會隨着消息的發送不停的“Ratcheting”。這是屬於非對稱加密的Forward Secrecy。

在sender的消息被ack之前,也就是新的ECC Key對交換成功之前,Message Key也會通過HKDF算法不停的“Ratcheting”,確保每條消息所使用的對稱密鑰也不相同。這是屬於對稱加密的Forward Secrecy。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章