9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

MITM対策にSwift4でCertificate Pinningをやってみた

Last updated at Posted at 2018-05-01

#はじめに
iOSアプリケーションの安全性を上げるために、MITM対策をCertificate Pinningをやってみました。

MITMやSSLとは?という方は下記のWikipediaを参考にしてください。
MITM SSL/TLS

#環境
・Xcode 9.3
・Swift 4.1
・macOS 10.3

#実装
通信を行うクラスにURLSessionDelegateを継承してください。

継承したクラスに下記のurlSessionメソッドを追加してください。

func urlSession(_ session: URLSession, didReceive challenge:URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
      let serverTrust = challenge.protectionSpace.serverTrust
      let certificate = SecTrustGetCertificateAtIndex(serverTrust!, 0)

      //ドメイン名を確認するpoliciesにSSLをセットする
      let policies = NSMutableArray()
      policies.add(SecPolicyCreateSSL(true, (challenge.protectionSpace.host as CFString)))
      SecTrustSetPolicies(serverTrust!, policies)
           
      //SSL証明書をチェックする
      var result: SecTrustResultType = SecTrustResultType(rawValue: 0)!
      SecTrustEvaluate(serverTrust!, &result)
      let isServerTrusted:Bool = result == SecTrustResultType.unspecified || result ==  SecTrustResultType.proceed
            
      //ローカルとリモートの証明書データを取得する
      let remoteCertificateData:NSData = SecCertificateCopyData(certificate!)
      //○○○に証明書ファイル名、□□□に型名を入れる
      let pathToCert = Bundle.main.path(forResource: "○○○", ofType: "□□□")

      let localCertificate:NSData = NSData(contentsOfFile: pathToCert!)!
            
      if (isServerTrusted && remoteCertificateData.isEqual(to: localCertificate as Data)) {
          let credential:URLCredential = URLCredential(trust: serverTrust!)
           completionHandler(.useCredential, credential)
      } else {
            completionHandler(.cancelAuthenticationChallenge, nil)
      }
}

これで基本的な実装は終了です。

後はこのようにすれば完成です。

  let configuration = URLSessionConfiguration.default
  let session = URLSession(configuration: configuration, delegate: self, delegateQueue:OperationQueue.main)
  var request = URLRequest(url:url)
  let task = session.dataTask(with: request) { data, response, error in
      //処理を書く
   }

実行確認はこちら等を参考に
Charlesで他社アプリの通信を覗く

#参考
Certificate pinning technique on iOS

9
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?