1. 程式人生 > >Android _實現SSL解決不受信任的證書問題

Android _實現SSL解決不受信任的證書問題

介紹

網路安全已成為大家最關心的問題. 如果你利用伺服器儲存客戶資料, 那你應該考慮使用 SSL 加密客戶跟伺服器之間的通訊. 隨著這幾年手機應用迅速崛起. 黑客也開始向手機應用轉移, 原因有下列3點:

  1. 手機系統各式各樣, 缺乏統一的標準.

  2. 許多程式設計師缺乏手機應用開發經驗.

  3. 更嚴重的是, 通過手機應用, 黑客可以得到手機使用者的隱私資料, 如:日程安排, 聯絡人資訊, 網頁瀏覽歷史記錄, 個人資料, 社交資料, 簡訊或者手機使用者所在的地理位置.

最為一個網路安全愛好者的我, 最近花了幾個月的時間對50到60安卓應用進行安全分析, 結果發現這些應用存在許多安全漏洞.

下面我主要講一講, 怎樣才能寫出比較安全的安卓程式碼.

背景

從最基本的開始講.

 下列程式碼用來開啟一個 http 連線.

?
1 2 3 URL urlConnection = new URL("http://www.codeproject.com/"); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

不要在 http連線中開啟:登陸頁面, 或是傳遞使用者名稱, 密碼, 銀行卡之類的重要個人資料. 這些重要個人資料應該通過 HTTPS 傳輸. (具體參看

HTTPS).

HTTPS是什麼?

HTTPS 其實就是個安全版的 http. HTTPS 能保證電子商務的交易安全. 如:網上銀行.

像 IE 或者火狐瀏覽器, 如果出現下面的掛鎖圖示.

為你的Android App實現自簽名的 SSL 證書

同時, 在瀏覽器的位址列中以 https:// 開頭, 這表示, 你的瀏覽器跟這個網站的資料往來都是安全的.

https 跟 http 的最大區別在於 https 多加了一個保障通訊安全的層.

為你的Android App實現自簽名的 SSL 證書

像下列程式碼這樣開啟一個 https 連線, 可以保障這個連線的資料通訊安全.

?
1 2 3 4 5 URL urlConnection = new URL("https://www.codeproject.com/"); HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection(); InputStream in = new BufferedInputStream(urlConnection.getInputStream());

HTTPS 通過 SSL/TLS 傳遞資料.

回到頂部

SSL/TLS:

SSL (Secure Sockets Layer) 是一種在客戶端跟伺服器端建立一個加密連線的安全標準. 一般用來加密網路伺服器跟瀏覽器, 或者是郵件伺服器跟郵件客戶端(如: Outlook)之間傳輸的資料.

SSL 能保障敏感資訊(如:銀行卡號, 社保卡號, 登陸憑證等)的傳輸安全. 一般情況下, 資料在瀏覽器跟伺服器之間的傳輸使用的是明文格式, 這種方式存在資料被竊取的風險. 如果黑客能攔截瀏覽器跟伺服器之間的通訊資料, 就能看到通訊的內容. 

回到頂部

SSL/HTTPS and X.509 證書概述

你要是對 SSL 或 X.509 證書一無所知, 那我大概解釋下. 對於那些打算用自簽名證書(self-signed certificate)的人來說, 需要了解自簽名證書跟花錢購買機構頒發的證書有什麼區別. 

首先我們需要了解下 SSL 證書究竟是個什麼東東? 其實它就包含倆部分: 1) 一個身份標識, 一個用來識別身份的東西, 有點類似警察叔叔通過護照或駕照查你的身份; 2) 一個公共金鑰, 這個用來給資料加密, 而且只有證書的持有者才能解密. 簡而言之, SSL 證書就倆個功能, 身份驗證跟保障通訊過程中的資料安全.

另外還有一點很重要. 那就是一個證書可以給另外一個證書“簽字”. 用 layman 的話說就是 Bob 用他自己的證書在別的證書上蓋上 “同意” 兩個紅紅的大字. 如果你信任 Bob (當然還有他的證書), 那麼你也可以信任由他簽發的證書. 在這個例子中, Bob 搖身一變, 成了證書頒發機構(Certificate Authority). 現在主流的瀏覽器都自帶一大堆受信任證書頒發機構(trusted Certificate Authorities)(比如:ThawteVerisign等).

最後我們講一講瀏覽器是怎麼使用證書的. 籠統的講, 當你開啟下列連線的時候 “https://www.yoursite.com” :

  1. 伺服器會給瀏覽器發一個證書.

  2. 瀏覽器會對比證書中的“common name”(有時也叫 “subject”) 跟伺服器的域名是否一樣. 例如, 一個從“www.yoursite.com” 網站發過來的證書就應該有一個內容是 “www.yoursite.com” 的 common name, 否則瀏覽器就會提示該證書有問題.

  3. 瀏覽器驗證證書真偽, 有點像門衛通過證件上的全息圖辨別你的證件是不是真的.  既然在現實生活中有人偽造別人的身份. 那麼在網路世界也就有人造假, 比如用你的域名“www.yoursite.com” 來偽造一個安全證書.  瀏覽器在驗證的時候, 會檢查這個證書是否是它信任機構頒發的, 如果不是, 那麼瀏覽器就會提示這個證書可能有問題. 當然, 使用者可以選擇無視警告, 繼續使用.

  4. 一旦證書通過驗證 (或是使用者無視警告, 繼續使用有問題的證書), 瀏覽器就開始利用證書中的公開金鑰加密資料並傳給伺服器.

回到頂部 回到頂部

TLS (SSL)中的加密

一旦伺服器發過來的證書通過驗證, 瀏覽器就會利用證書中包含的公共金鑰加密某個指定的共享金鑰, 然後發給伺服器. 這個加密過的共享金鑰只能用伺服器的私有金鑰才能解密(非對稱加密), 別人無法解密出其中的內容. 伺服器把解密出來的共享金鑰儲存起來, 供本次連線會話專用. 從現在開始, 伺服器跟瀏覽器之間的所有通訊資訊都用這個共享金鑰加密解密(對稱加密).

為你的Android App實現自簽名的 SSL 證書

理論部分就這麼多, 下面我們來看幾個例子.

在瀏覽器中開啟網站 mail.live.com , 位址列中會出現一個綠色圖示, http 也會變成 https.

單擊這個綠色圖示, 然後點證書資訊連線, 就能看到下列內容.

為你的Android App實現自簽名的 SSL 證書

這是個 SSL 證書, 該證書是 Verisign 給 mail.live.cm 頒發的.

Verisign 是一個證書頒發機構, 它提示你的瀏覽器正在連線的網站是: mail.live.com, 需要跟這個網站的伺服器建立一條安全連線進行通訊, 避免他人攔截或篡改瀏覽器跟伺服器之間傳遞的資料.

回到頂部

MITM 攻擊

MITM 攻擊(MITMA)是指: 黑客攔截篡改網路中的通訊資料

被動 MITMA 是指黑客只能竊取通訊資料, 而在主動 MITMA 中, 黑客除了竊取資料, 還能篡改通訊資料. 黑客利用 MITMA 方式攻擊手機要比攻擊臺式電腦容易的多. 這主要是因為使用手機的環境在不固定, 有些地方用手機連線上網並不安全, 尤其是那些對公眾免費開放的無線網路熱點.

證書頒發機構(CA)

·Symantec (which bought VeriSign's SSL interests and owns Thawte and Geotrust) 38.1% 市場份額

Jelly bean 版本的安卓系統中, 你可以在下列路徑中找到證書頒發機構:

設定 -> 安全 -> 受信任的憑證.

Https 連線

?
1 2 3 URL url = new URL("https://www.example.com/");    HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection();    InputStream in = urlConnection.getInputStream();

如果你連線的伺服器(www.example.com)傳過來的證書是由機構頒發的, 這段程式碼就能正常執行.

但是如果你連的伺服器用的是自己頒發的證書(self-singed certificate), 那就會出現錯誤.

回到頂部

什麼是自簽名證書( self-signed certicates)

自簽名證書就是沒有通過受信任的證書頒發機構, 自己給自己頒發的證書.

SSL 證書大致分三