Swift實現HTTPS接口加密通訊

在使用 Alamofire 的 Session 實現無證書訪問 HTTPS 接口時,如果要求抓包不是明文(即防止中間人攻擊和抓包工具如 Charles/Fiddler 解密 HTTPS 流量),可以通過以下方式實現:


1. 使用 SSL Pinning(證書綁定)

SSL Pinning 是一種防止中間人攻擊的技術,通過將服務器的公鑰或證書嵌入客戶端,確保客戶端只與特定的服務器通信。

實現步驟:

  1. 獲取服務器的證書
    從服務器獲取 .cer.der 格式的證書文件,并將其添加到 Xcode 項目中。

  2. 配置 Alamofire 的 ServerTrustManagerServerTrustEvaluating
    使用 Alamofire 的 ServerTrustManagerServerTrustEvaluating 來實現 SSL Pinning。

    import Alamofire
    
    // 1. 加載證書
    let certificatePath = Bundle.main.path(forResource: "your_certificate", ofType: "cer")!
    let certificateData = try! Data(contentsOf: URL(fileURLWithPath: certificatePath))
    
    // 2. 創建 ServerTrustEvaluating
    let evaluator = PinnedCertificatesTrustEvaluator(certificates: [certificateData])
    
    // 3. 配置 ServerTrustManager
    let serverTrustManager = ServerTrustManager(evaluators: ["yourserver.com": evaluator])
    
    // 4. 創建 Session
    let session = Session(serverTrustManager: serverTrustManager)
    
    // 5. 發起請求
    session.request("https://yourserver.com/api").response { response in
        debugPrint(response)
    }
    
  3. 效果
    抓包工具(如 Charles)將無法解密 HTTPS 流量,因為客戶端只信任綁定的證書。


2. 禁用明文傳輸(防止 HTTP 請求)

確保應用只使用 HTTPS,禁用 HTTP 請求。

實現步驟:

Info.plist 中添加以下配置:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <false/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>yourserver.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <false/>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <true/>
        </dict>
    </dict>
</dict>

3. 使用自定義的 URLSessionDelegate

如果需要更細粒度的控制,可以實現 URLSessionDelegateurlSession(_:didReceive:completionHandler:) 方法,手動驗證服務器證書。

實現步驟:

import Alamofire

class CustomSessionDelegate: SessionDelegate {
    override func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        // 驗證服務器證書
        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
            if let serverTrust = challenge.protectionSpace.serverTrust {
                // 自定義驗證邏輯
                let credential = URLCredential(trust: serverTrust)
                completionHandler(.useCredential, credential)
                return
            }
        }
        completionHandler(.performDefaultHandling, nil)
    }
}

// 創建自定義 Session
let session = Session(delegate: CustomSessionDelegate())

// 發起請求
session.request("https://yourserver.com/api").response { response in
    debugPrint(response)
}

4. 防止抓包工具注入證書

抓包工具(如 Charles)通常會要求用戶安裝自定義根證書來解密 HTTPS 流量。可以通過以下方式防止抓包工具注入證書:

實現步驟:

  1. 檢測設備是否安裝了抓包工具的證書
    檢查設備是否安裝了 Charles/Fiddler 等工具的根證書。

    func isProxyEnabled() -> Bool {
        if let proxySettings = CFNetworkCopySystemProxySettings()?.takeRetainedValue() as? [String: Any],
           let httpProxy = proxySettings["HTTPProxy"] as? String, !httpProxy.isEmpty {
            return true
        }
        return false
    }
    
  2. 拒絕請求或提示用戶
    如果檢測到抓包工具,可以拒絕請求或提示用戶關閉代理。


5. 使用雙向 TLS(mTLS)

雙向 TLS(mTLS)要求客戶端和服務器都提供證書,進一步增加安全性。

實現步驟:

  1. 獲取客戶端證書
    從服務器獲取客戶端證書(.p12 文件)。

  2. 加載客戶端證書
    在代碼中加載客戶端證書并配置 Alamofire。

    import Alamofire
    
    // 1. 加載客戶端證書
    let certificatePath = Bundle.main.path(forResource: "client_certificate", ofType: "p12")!
    let certificateData = try! Data(contentsOf: URL(fileURLWithPath: certificatePath))
    
    // 2. 創建 URLCredential
    let credential = URLCredential(pkcs12: certificateData, password: "your_password")
    
    // 3. 創建 Session
    let session = Session()
    
    // 4. 發起請求
    session.request("https://yourserver.com/api")
        .authenticate(with: credential)
        .response { response in
            debugPrint(response)
        }
    

6. 總結

  • SSL Pinning 是最常用的防止抓包工具解密 HTTPS 流量的方法。
  • 禁用明文傳輸 確保應用只使用 HTTPS。
  • 自定義 URLSessionDelegate 提供更細粒度的控制。
  • 檢測抓包工具 可以防止用戶使用抓包工具。
  • 雙向 TLS 提供更高的安全性,但實現復雜度較高。

根據你的需求選擇合適的方法,通常 SSL Pinning 是最常用的解決方案。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,321評論 6 543
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,559評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,442評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,835評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,581評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,922評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,931評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,096評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,639評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,374評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,591評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,104評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,789評論 3 349
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,196評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,524評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,322評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,554評論 2 379

推薦閱讀更多精彩內容