1. 程式人生 > 其它 >iOS 防止charles抓包

iOS 防止charles抓包

方案一:檢查手機Wifi是否設定了代理

    public func fetchHttpProxy() -> Bool {
        guard let proxy = CFNetworkCopySystemProxySettings()?.takeUnretainedValue() else { return false }
        guard let dict = proxy as? [String: Any] else { return false }
        guard let HTTPProxy = dict["HTTPProxy"] as? String else { return false }
        if(HTTPProxy.count>0){
            return true;
        }
        return false;
    }

 1.以場景介面為例,設定了代理檢測,手機開啟代理,存在代理就直接返回,請求失敗。

    func getSelectedFamilyDeviceSomeInfo(parameters : Any?, succeed : @escaping([String : Any]?) -> (), failure : @escaping(Error?) -> ()) {
        let requestUrl:String = SEVER_URL.appending("/developStage/devicegroup/v2/group/someInfo").addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
        print(parameters ?? "")
        NSLog("RequestUrl : "+requestUrl)
        
        if self.fetchHttpProxy() {
            print("++++++++++++設定了代理,不讓請求=======")
            failure("設定了代理" as? Error)
            return
        }else{
            print("++++++++++++沒設定代理,自由請求=======")
        }

        
        // 成功閉包
        let successBlock = { (task: URLSessionDataTask, responseObj: Any?) in
            succeed(responseObj as? [String : Any])
        }
        // 失敗的閉包
        let failureBlock = { (task: URLSessionDataTask?, error: Error) in
            failure(error)
        }
        //accesstoken 加入請求頭
        getAccessToken(success: {
            self.setHttpHeaderBasicProperty()
            self.post(requestUrl, parameters: parameters, progress: nil, success: successBlock, failure: failureBlock)
        }) {
            failure("Please sign in first" as? Error)
        }
    }

 2.註釋代理檢測,請求正常,介面正常展示,能抓取到場景介面資料

 方案二:對證書的驗證

1.客戶端需要證書(Certification file), .cer格式的檔案。(找伺服器要,有可能需要轉化證書格式)

2、把證書加進專案中,把生成的.cer證書檔案直接拖到你專案的相關資料夾中,記得勾選Copy items if neede和Add to targets。

3、引數名意思

AFSecurityPolicy

SSLPinningMode

AFSecurityPolicy是AFNetworking中網路通訊安全策略模組。它提供三種SSL Pinning Mode

/**

 ## SSL Pinning Modes

 The following constants are provided by `AFSSLPinningMode` as possible SSL pinning modes.

 enum {

 AFSSLPinningModeNone,

 AFSSLPinningModePublicKey,

 AFSSLPinningModeCertificate,

 }

 `AFSSLPinningModeNone`

 Do not used pinned certificates to validate servers.

 `AFSSLPinningModePublicKey`

 Validate host certificates against public keys of pinned certificates.

 `AFSSLPinningModeCertificate`

 Validate host certificates against pinned certificates.

*/

AFSSLPinningModeNone:完全信任伺服器證書;

AFSSLPinningModePublicKey:只比對伺服器證書和本地證書的Public Key是否一致,如果一致則信任伺服器證書;

AFSSLPinningModeCertificate:比對伺服器證書和本地證書的所有內容,完全一致則信任伺服器證書;

選擇那種模式呢?

AFSSLPinningModeCertificate:最安全的比對模式。但是也比較麻煩,因為證書是打包在APP中,如果伺服器證書改變或者到期,舊版本無法使用了,我們就需要使用者更新APP來使用最新的證書。

AFSSLPinningModePublicKey:只比對證書的Public Key,只要Public Key沒有改變,證書的其他變動都不會影響使用。
如果你不能保證你的使用者總是使用你的APP的最新版本,所以我們使用AFSSLPinningModePublicKey。

allowInvalidCertificates

1 2 3 4 /**  Whether or not to trust servers with an invalid or expired SSL certificates. Defaults to `NO`.  */ @property (nonatomic, assign) BOOL allowInvalidCertificates;

是否信任非法證書,預設是NO。

validatesDomainName

1 2 3 4 /**  Whether or not to validate the domain name in the certificate's CN field. Defaults to `YES`.  */ @property (nonatomic, assign) BOOL validatesDomainName;

是否校驗證書中DomainName欄位,它可能是IP,域名如*.google.com,預設為YES,嚴格保證安全性。

4、使用AFSecurityPolicy設定SLL Pinning

1 2 3 4 5 6 7 8 9 10 11 12 13 14 + (AFHTTPSessionManager *)manager {     static AFHTTPSessionManager *manager = nil;     static dispatch_once_t onceToken;     dispatch_once(&onceToken, ^{               NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];         manager =  [[AFHTTPSessionManager alloc] initWithSessionConfiguration:config];           AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey withPinnedCertificates:[AFSecurityPolicy certificatesInBundle:[NSBundle mainBundle]]];         manager.securityPolicy = securityPolicy;     });     return manager; }