AFNetworking 中的客戶端驗證服務(wù)端

為了防止中間人攻擊并蝗,需要在客戶端中內(nèi)置SSL證書戏仓,來驗證服務(wù)端證書的有效性凛驮。

  • AFNetworking 定義了AFSecurityPolicy類實現(xiàn)對服務(wù)端的配置管理,其中AFSSLPinningMode 中定義的AFSSLPinningModePublicKey郭宝、AFSSLPinningModeCertificate均需要客戶端中內(nèi)置服務(wù)器的SSL證書荠割。
typedef NS_ENUM(NSUInteger, AFSSLPinningMode) {
    AFSSLPinningModeNone,//不需要任何驗證
    AFSSLPinningModePublicKey,//驗證公鑰
    AFSSLPinningModeCertificate,//驗證證書
};

另外瞻惋,可通過如下命令獲取服務(wù)端的證書小染。

openssl s_client -connect ***.***.com.cn:443 </dev/null 2>/dev/null | openssl x509 -outform DER > https.cer
  • 類中主要定義了如下方法進行驗證,注釋中已經(jīng)很明確箱舞。
// 客戶端通過本地證書或公鑰對服務(wù)端進行驗證
- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust
                  forDomain:(NSString *)domain
{
    if (domain && self.allowInvalidCertificates && self.validatesDomainName && (self.SSLPinningMode == AFSSLPinningModeNone || [self.pinnedCertificates count] == 0)) {
        // https://developer.apple.com/library/mac/documentation/NetworkingInternet/Conceptual/NetworkingTopics/Articles/OverridingSSLChainValidationCorrectly.html
        //  According to the docs, you should only trust your provided certs for evaluation.
        //  Pinned certificates are added to the trust. Without pinned certificates,
        //  there is nothing to evaluate against.
        //
        //  From Apple Docs:
        //          "Do not implicitly trust self-signed certificates as anchors (kSecTrustOptionImplicitAnchors).
        //           Instead, add your own (self-signed) CA certificate to the list of trusted anchors."
        NSLog(@"In order to validate a domain name for self signed certificates, you MUST use pinning.");
        return NO;
    }

    NSMutableArray *policies = [NSMutableArray array];
    if (self.validatesDomainName) {//如果需要驗證domain
        //設(shè)置驗證策略  那么就使用SecPolicyCreateSSL函數(shù)創(chuàng)建驗證策略
        [policies addObject:(__bridge_transfer id)SecPolicyCreateSSL(true, (__bridge CFStringRef)domain)];
    } else {
        //只驗證x509標準的證書
        [policies addObject:(__bridge_transfer id)SecPolicyCreateBasicX509()];
    }
    // 設(shè)置驗證serverTrust 的策略遍坟, 告訴系統(tǒng)在驗證serverTrust的時候考慮域名的正確性
    SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef)policies);

    if (self.SSLPinningMode == AFSSLPinningModeNone) {
        //如果為AFSSLPinningModeNone,則要么不驗證晴股,要么只使用系統(tǒng)對證書進行驗證
        return self.allowInvalidCertificates || AFServerTrustIsValid(serverTrust);
    } else if (!AFServerTrustIsValid(serverTrust) && !self.allowInvalidCertificates) {
        //如果不允許無效證書政鼠,且系統(tǒng)沒有驗證通過serverTrust
        return NO;
    }

    switch (self.SSLPinningMode) {
        case AFSSLPinningModeNone:
        default:
            return NO;
        case AFSSLPinningModeCertificate: {
            NSMutableArray *pinnedCertificates = [NSMutableArray array];//存放客戶端證書
            for (NSData *certificateData in self.pinnedCertificates) {
                [pinnedCertificates addObject:(__bridge_transfer id)SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificateData)];
            }
            
            //給serverTrust設(shè)置錨點證書,即如果以后再次去驗證serverTrust队魏,會從錨點證書去找是否匹配公般。
            SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)pinnedCertificates);
            //用系統(tǒng)CA證書 驗證serverTrust的有效性
            if (!AFServerTrustIsValid(serverTrust)) {
                return NO;
            }

            // obtain the chain after being validated, which *should* contain the pinned certificate in the last position (if it's the Root CA)
            //獲取服務(wù)端證書鏈
            NSArray *serverCertificates = AFCertificateTrustChainForServerTrust(serverTrust);
            
            for (NSData *trustChainCertificate in [serverCertificates reverseObjectEnumerator]) {
                //如果本地證書 包含 在服務(wù)端證書鏈中
                if ([self.pinnedCertificates containsObject:trustChainCertificate]) {
                    return YES;
                }
            }
            
            return NO;
        }
        case AFSSLPinningModePublicKey: {
            NSUInteger trustedPublicKeyCount = 0;
            //獲取服務(wù)端公鑰鏈
            NSArray *publicKeys = AFPublicKeyTrustChainForServerTrust(serverTrust);

            for (id trustChainPublicKey in publicKeys) {
                for (id pinnedPublicKey in self.pinnedPublicKeys) {
                    if (AFSecKeyIsEqualToKey((__bridge SecKeyRef)trustChainPublicKey, (__bridge SecKeyRef)pinnedPublicKey)) {
                        //驗證公鑰匹配的個數(shù)
                        trustedPublicKeyCount += 1;
                    }
                }
            }
            return trustedPublicKeyCount > 0;
        }
    }
    
    return NO;
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市胡桨,隨后出現(xiàn)的幾起案子官帘,更是在濱河造成了極大的恐慌,老刑警劉巖昧谊,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件刽虹,死亡現(xiàn)場離奇詭異,居然都是意外死亡呢诬,警方通過查閱死者的電腦和手機涌哲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來尚镰,“玉大人阀圾,你說我怎么就攤上這事」钒Γ” “怎么了初烘?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長分俯。 經(jīng)常有香客問我肾筐,道長,這世上最難降的妖魔是什么缸剪? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任吗铐,我火速辦了婚禮,結(jié)果婚禮上杏节,老公的妹妹穿的比我還像新娘唬渗。我一直安慰自己讥此,他們只是感情好,可當我...
    茶點故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布谣妻。 她就那樣靜靜地躺著,像睡著了一般卒稳。 火紅的嫁衣襯著肌膚如雪蹋半。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天充坑,我揣著相機與錄音减江,去河邊找鬼。 笑死捻爷,一個胖子當著我的面吹牛辈灼,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播也榄,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼巡莹,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了甜紫?” 一聲冷哼從身側(cè)響起降宅,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎囚霸,沒想到半個月后腰根,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡拓型,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年额嘿,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片劣挫。...
    茶點故事閱讀 38,626評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡册养,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出压固,到底是詐尸還是另有隱情捕儒,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布邓夕,位于F島的核電站刘莹,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏焚刚。R本人自食惡果不足惜点弯,卻給世界環(huán)境...
    茶點故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望矿咕。 院中可真熱鬧抢肛,春花似錦狼钮、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至福稳,卻和暖如春涎拉,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背的圆。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工鼓拧, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人越妈。 一個月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓季俩,卻偏偏與公主長得像,于是被迫代替她去往敵國和親梅掠。 傳聞我的和親對象是個殘疾皇子酌住,可洞房花燭夜當晚...
    茶點故事閱讀 43,494評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 這篇文章是我一邊學(xué)習(xí)證書驗證一邊記錄的內(nèi)容,稍微整理了下阎抒,共扯了三部分內(nèi)容: HTTPS 簡要原理赂韵;數(shù)字證書的內(nèi)容...
    左邊飛來一只狗閱讀 3,283評論 2 5
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)挠蛉,斷路器祭示,智...
    卡卡羅2017閱讀 134,629評論 18 139
  • 原文地址 http://blog.csdn.net/u012409247/article/details/4985...
    0fbf551ff6fb閱讀 3,516評論 0 13
  • 一、作用 不使用SSL/TLS的HTTP通信谴古,就是不加密的通信质涛。所有信息明文傳播,帶來了三大風(fēng)險掰担。 (1)竊聽風(fēng)險...
    XLsn0w閱讀 10,496評論 2 44
  • “公主快走汇陆!” “不要!带饱!” 慘叫聲和著溫熱的液體濺到君緋月的臉上毡代,濃的化不開的血腥氣此刻是那...
    洱易閱讀 239評論 0 1