網際網路通訊安全之終端資料保護

語言: CN / TW / HK

“xx 偵探,技術高超,輕鬆獲取對方位置或通訊內容。” 關注【融雲全球網際網路通訊雲】瞭解更多

你或許也在網上遇到過這類所謂“私家偵探”的違規小廣告,抑或是在法制節目中看到過類似“假定位真詐騙”的普法故事。

這類事件頻發,佐證著有不少人想通過非法途徑窺探他人隱私達到不法目的事實。這就是在我們把生活、工作的方方面面轉移到線上的過程中,每天都要面對的通訊安全挑戰。

在通訊安全這個議題之下,我們此前已經與大家分享了​ ​鏈路安全​ ​​、​ ​WebRTC 傳輸安全機制​ ​​、​ ​端到端加密技術​ ​等主題。

隨著 SSL/TLS 的普及和各種安全產品的應用,黑客直接通過鏈路或入侵伺服器來獲取使用者的通訊訊息已經是幾乎不可能的事情了。

這種情況下,通過植入木馬的方式來獲取通訊內容就變成了他們行不法勾當的重要途徑。

如何防止手機等終端被木馬植入?在使用者層面,就需要大傢俱備良好的安全意識,比如安裝防毒軟體、不點選陌生連結、不越獄或 Root 系統等等。

而今天我們將要探討的議題是, 假設我們的裝置已經被植入了木馬,那如何從軟體層面做最後的防護,以保證使用者通訊訊息的安全性和私密性

需要注意的是,當系統被植入木馬後,一般不會更改軟體本體,而是通過本地網路代理或讀取關鍵位置的檔案來獲取想要監聽的內容。而本地網路代理我們在​ ​鏈路安全​ ​一文中已經分享過,可以通過開啟 SSL/TLS 的方式防止資訊被監聽。

資料儲存安全

即時通訊系統一般都存在著終端訊息儲存的特性,以方便使用者離線檢視已經接收過的訊息。而這些訊息一般都會使用檔案級資料庫來進行儲存。

使用資料庫的優勢在於,方便對資料進行增刪改查,而且也不會出現太大的效能問題。

其中 SQLite 因其小巧、開源和高效能成為了眾多終端軟體資料儲存的首選方案。

那麼在 SQLite 中如何做訊息的加密儲存呢?

方案一  對要儲存的訊息進行加密

對要插入到資料庫中的訊息先進行 AES 加密,加密完成後再插入到資料中,使用的時候先從資料庫中取出,然後再進行解密就可以正常使用了。

這種方法優勢明顯,但是劣勢也非常致命——如果需要對訊息進行模糊查詢,那該訊息就不能加密,這樣一來 產品需要安全需求 就形成了矛盾體。所以,我們一般 不會選取這樣的方式

方案二  對資料進行加密

SQLite 3 的開源釋出版沒有提供加密功能,但是其匯出標頭檔案中有 sqlite3_key  和 sqlite3_rekey 的定義,可以用來實現資料庫加密。

有加密實現的版本還需要在預編譯中定義預處理巨集 SQLITE_HAS_CODEC 才能開啟這幾個函式的功能。

sqlite3_key

sqlite3_key 是輸入金鑰,如果資料庫已加密必須先執行此函式並輸入正確金鑰才能進行操作;如果資料庫沒有加密,執行此函式後進行資料庫操作反而會出現“此資料庫已加密或不是一個數據庫檔案”的錯誤。

// db 是指定資料庫,pKey 是金鑰,nKey 是金鑰長度。
int sqlite3_key(sqlite3 *db, const void *pKey, int nKey) 
// 例:
sqlite3_key(db, "abc", 3);

sqlite3_rekey

sqlite3_rekey 是變更金鑰或給沒有加密的資料庫新增金鑰或清空金鑰,變更金鑰或清空金鑰前必須先正確執行 sqlite3_key。

在正確執行 sqlite3_rekey 之後在 sqlite3_close 關閉資料庫之前可以正常操作資料庫,不需要再執行  sqlite3_key。

// 引數同上 
int sqlite3_rekey(sqlite3 *db, const void *pKey, int nKey)

新增資料庫密碼:如果想要新增密碼,可以在建立資料庫檔案之後,關閉資料庫檔案之前的任何時刻呼叫 sqlite3_key 函式即可。

讀取資料庫資料:開啟資料檔案後,呼叫 sqlite3_key 函式,即可。( 如果資料庫沒有加密,執行此函式後進行資料庫操作反而會出現“此資料庫已加密或不是一個數據庫檔案”的錯誤;經測試,只能在新建資料庫時設定密碼!

修改資料庫密碼:首先你需要使用當前的密碼正確開啟資料庫,之後便可呼叫 sqlite3_rekey(db,"112233",6) 來更改資料庫密碼。

除了直接使用 SQLite 3 中的 sqlite3_key 外,還有很多其他語言的 SQLite 開源框架也提供了資料庫加密能力,如:SQLCipher、wxSQLite3 等。

目前 SQLite 3 支援這兩個介面的版本到 3.31.1, 其後版本不再支援,建議採用一些開源庫。

資料庫密碼保護

資料庫的密碼應避免直接在程式碼或配置檔案中儲存。因為一旦程式被反編譯後其保密性也就不存在了,所以 資料庫的密碼也需要被保護起來

首先,最安全的做法是客戶端完全不儲存資料庫的密碼,每次開啟終端軟體時都必須保證網路正常,且可以完整地經過伺服器的使用者鑑權,才能返回資料庫密碼。

而伺服器需要為每個使用者的每個裝置生成不同的密碼,這樣就可以有效防止以下兩種情況:

①一個終端上有多個使用者的場景下,一個密碼洩露導致整個終端被破解;

②一個使用者密碼被破解後可以檢視這個使用者其他裝置上的資料。

(資料庫密碼儲存流程)

通過以上流程圖我們可以簡單瞭解資料庫密碼的儲存方式。但該方法存在一個問題,即:如果客戶端有離線開啟需求,這種方案是無法滿足的。

離線對資料庫操作的需求存在安全隱患,都是可以被破解的,這就是 安全便捷 的衝突。

但是我們可以通過設定複雜規則使破解難度增大,在設計規則時我們至少保證遵守以下幾條原則:

① 每個裝置上的每個使用者的密碼不一樣。

② 每次得到資料密碼結果必須一致。

③ 密碼結果不在終端儲存。

④ 終端生成密碼的程式碼必須進行安全加固。

例如:我們通過將裝置標識與使用者標識進行 Hash 得到資料庫密碼。

現在,資訊保安問題日益嚴峻,在實際生活中,我們無法保證所使用的終端軟體都採用加密資料儲存方式。

因此,保持一個良好的使用習慣,不點選陌生連結,不安裝非正規渠道的應用,並在終端上安裝防毒軟體和其他的安全產品,才能最大限度保障我們資訊及隱私不被不法之徒獲得和利用。