使用Swift和NSURLSession固定的​​iOS证书

前端之家收集整理的这篇文章主要介绍了使用Swift和NSURLSession固定的​​iOS证书前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
如何在Swift中将证书固定添加到NSURLSession?

OWASP website仅包含Objective-C和NSURLConnection的示例.

Swift 3更新:

只需为NSURLSessionDelegate定义一个委托类并实现didReceiveChallenge函数(此代码改编自objective-c OWASP示例):

  1. class NSURLSessionPinningDelegate: NSObject,URLSessionDelegate {
  2.  
  3. func urlSession(_ session: URLSession,didReceive challenge: URLAuthenticationChallenge,completionHandler: @escaping (URLSession.AuthChallengeDisposition,URLCredential?) -> Swift.Void) {
  4.  
  5. // Adapted from OWASP https://www.owasp.org/index.PHP/Certificate_and_Public_Key_Pinning#iOS
  6.  
  7. if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
  8. if let serverTrust = challenge.protectionSpace.serverTrust {
  9. var secresult = SecTrustResultType.invalid
  10. let status = SecTrustEvaluate(serverTrust,&secresult)
  11.  
  12. if(errSecSuccess == status) {
  13. if let serverCertificate = SecTrustGetCertificateAtIndex(serverTrust,0) {
  14. let serverCertificateData = SecCertificateCopyData(serverCertificate)
  15. let data = CFDataGetBytePtr(serverCertificateData);
  16. let size = CFDataGetLength(serverCertificateData);
  17. let cert1 = NSData(bytes: data,length: size)
  18. let file_der = Bundle.main.path(forResource: "certificateFile",ofType: "der")
  19.  
  20. if let file = file_der {
  21. if let cert2 = NSData(contentsOfFile: file) {
  22. if cert1.isEqual(to: cert2 as Data) {
  23. completionHandler(URLSession.AuthChallengeDisposition.useCredential,URLCredential(trust:serverTrust))
  24. return
  25. }
  26. }
  27. }
  28. }
  29. }
  30. }
  31. }
  32.  
  33. // Pinning Failed
  34. completionHandler(URLSession.AuthChallengeDisposition.cancelAuthenticationChallenge,nil)
  35. }
  36.  
  37. }

(你可以找到一个Gist for Swift 2 here – from the initial answer)

然后使用openssl为您的网站创建.der文件

  1. openssl s_client -connect my-https-website.com:443 -showcerts < /dev/null | openssl x509 -outform DER > my-https-website.der

并将其添加到xcode项目中.仔细检查它是否存在于“复制包资源”列表中的“构建阶段”选项卡中.否则将其拖放到此列表中.

最后在您的代码中使用它来发出URL请求:

  1. if let url = NSURL(string: "https://my-https-website.com") {
  2.  
  3. let session = URLSession(
  4. configuration: URLSessionConfiguration.ephemeral,delegate: NSURLSessionPinningDelegate(),delegateQueue: nil)
  5.  
  6.  
  7. let task = session.dataTask(with: url as URL,completionHandler: { (data,response,error) -> Void in
  8. if error != nil {
  9. print("error: \(error!.localizedDescription): \(error!)")
  10. } else if data != nil {
  11. if let str = NSString(data: data!,encoding: String.Encoding.utf8.rawValue) {
  12. print("Received data:\n\(str)")
  13. } else {
  14. print("Unable to convert data to text")
  15. }
  16. }
  17. })
  18.  
  19. task.resume()
  20. } else {
  21. print("Unable to create NSURL")
  22. }

猜你在找的Swift相关文章