CURL組建中,HTTPS使用ip地址連接時候,SSL安全驗證方法!

1.背景

1.蘋果最近調整了HTTP連接的思路,要求iOS開發代碼中所有的http連接都必須使用,https安全連接方式。

2.在實現HTTP服務中,會有種VIP的保障邏輯。在域名解析失敗(DNS劫持是其中一種情況)而無法連接時候,會內置ip地址,保證在最壞的情況下,可以連通服務。

那麼問題來了,HTTPS直接使用HOST爲ip地址的時候,是無法正確使用SSL校驗安全證書的,因爲證書和域名綁定。

2.環境

curl組件c實現庫,iOS開發工程

3.方案

實現方式只是在現有curl組件實現的,http邏輯邏輯基礎上補充。具體完整curl實現http請求邏輯,待補充。

原理:通過IP直接訪問網站,解決DNS劫持問題。DNS劫持中,對於HTTPS請求,有SSL校驗安全證書的過程,這個時候HOST參數對應的域名是被綁定到證書上,進行安全校驗,而IP是無法通過校驗的。這個時候只有在SSL校驗之前修改HOST參數爲實際綁定的域名,才能完成SSL安全校驗。這個時候就涉及到CURL組件裏面setOption(CURLOPT_SSL_CTX_FUNCTION, *sslctx_function);設置。找到在SSL校驗之前修改參數的時機,具體實現如下。


添加代碼以及調試邏輯主要是在初始化時候添加如下三行代碼:

  setOption(CURLOPT_SSL_CTX_FUNCTION, *sslctx_function);
        setOption(CURLOPT_DEBUGFUNCTION, my_trace);
        setOption(CURLOPT_VERBOSE, 1L); 

sslctx_function 和 my_trace 方法邏輯如下:
static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm)
{
    if (curl) {XXX
        struct curl_slist *list = NULL;
        list = curl_slist_append(list, "Host: XXX.XXX.XXX.XXX:8888");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, list);
    }
    
    /* all set to go */
    return CURLE_OK;
}

static int my_trace(CURL *handle, curl_infotype type, char *data, size_t size, void *userp)
{
    const char *text;
    (void)handle; /* prevent compiler warning */
    (void)userp;
    
    char buf[1024] = {0};
    snprintf(buf, size, "%s type %d", data, type);
    mylog("%s", buf);
    
    switch (type) {
        case CURLINFO_TEXT:
            fprintf(stderr, "== Info: %s", data);
        default: /* in case a new one is introduced to shock us */
            return 0;
            
        case CURLINFO_HEADER_OUT:
            text = "=> Send header";
            break;
        case CURLINFO_DATA_OUT:
            text = "=> Send data";
            break;
        case CURLINFO_SSL_DATA_OUT:
            text = "=> Send SSL data";
            break;
        case CURLINFO_HEADER_IN:
            text = "<= Recv header";
            break;
        case CURLINFO_DATA_IN:
            text = "<= Recv data";
            break;
        case CURLINFO_SSL_DATA_IN:
            text = "<= Recv SSL data";
            break;
    }
    
    if (text)
mylog("== %s", text);
    }
    
//    dump(text, stderr, (unsigned char *)data, size);
    return 0;

4.結論

5.參考

curl中日誌追蹤實現 -- https://curl.haxx.se/libcurl/c/CURLOPT_DEBUGFUNCTION.html

實現思路參考 -- https://github.com/tencentyun/httpdns-ios-sdk


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