Swift - 使用SwiftHTTP通过HTTPS进行网络请求,及证书的使用
1
2
3
4
5
|
< key >NSAppTransportSecurity</ key >
< dict >
< key >NSAllowsArbitraryLoads</ key >
< true />
</ dict >
|
3,使用两个证书进行双向验证,以及网络请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
import UIKit
import SwiftHTTP
class ViewController : UIViewController {
override func viewDidLoad() {
super .viewDidLoad()
do {
let opt = try HTTP . GET ( "https://192.168.1.112:8443" )
opt.auth = { challenge in
//认证服务器证书
if challenge.protectionSpace.authenticationMethod
== NSURLAuthenticationMethodServerTrust {
print ( "服务端证书认证!" )
let serverTrust: SecTrust = challenge.protectionSpace.serverTrust!
let certificate = SecTrustGetCertificateAtIndex (serverTrust, 0)!
let remoteCertificateData
= CFBridgingRetain ( SecCertificateCopyData (certificate))!
let cerPath = Bundle .main.path(forResource: "tomcat" , ofType: "cer" )!
let cerUrl = URL (fileURLWithPath:cerPath)
let localCertificateData = try! Data (contentsOf: cerUrl)
if (remoteCertificateData.isEqual(localCertificateData)
== true ) {
let credential = URLCredential (trust: serverTrust)
challenge.sender?.use(credential, for : challenge)
return URLCredential (trust: challenge.protectionSpace.serverTrust!)
} else {
return nil
}
}
//认证客户端证书
else if challenge.protectionSpace.authenticationMethod
== NSURLAuthenticationMethodClientCertificate
{
print ( "客户端证书认证!" )
//获取客户端证书相关信息
let identityAndTrust: IdentityAndTrust = self .extractIdentity();
let urlCredential: URLCredential = URLCredential (
identity: identityAndTrust.identityRef,
certificates: identityAndTrust.certArray as ? [ AnyObject ],
persistence: URLCredential . Persistence .forSession)
return urlCredential
}
// 其它情况(不接受认证)
else {
print ( "其它情况(不接受认证)" )
return nil
}
}
opt.start { response in
print ( "访问成功,获取数据如下:" )
print (response.text)
}
} catch let error {
print ( "请求失败: \(error)" )
}
}
//获取客户端证书相关信息
func extractIdentity() -> IdentityAndTrust {
var identityAndTrust: IdentityAndTrust !
var securityError: OSStatus = errSecSuccess
let path: String = Bundle .main.path(forResource: "mykey" , ofType: "p12" )!
let PKCS12Data = NSData (contentsOfFile:path)!
let key : NSString = kSecImportExportPassphrase as NSString
let options : NSDictionary = [key : "123456" ] //客户端证书密码
//create variable for holding security information
//var privateKeyRef: SecKeyRef? = nil
var items : CFArray ?
securityError = SecPKCS12Import ( PKCS12Data , options, &items)
if securityError == errSecSuccess {
let certItems: CFArray = items as CFArray !;
let certItemsArray: Array = certItems as Array
let dict: AnyObject ? = certItemsArray.first;
if let certEntry: Dictionary = dict as ? Dictionary < String , AnyObject > {
// grab the identity
let identityPointer: AnyObject ? = certEntry[ "identity" ]
let secIdentityRef: SecIdentity = identityPointer as ! SecIdentity !
print ( "\(identityPointer) :::: \(secIdentityRef)" )
// grab the trust
let trustPointer: AnyObject ? = certEntry[ "trust" ]
let trustRef: SecTrust = trustPointer as ! SecTrust
print ( "\(trustPointer) :::: \(trustRef)" )
// grab the cert
let chainPointer: AnyObject ? = certEntry[ "chain" ]
identityAndTrust = IdentityAndTrust (identityRef: secIdentityRef,
trust: trustRef, certArray: chainPointer!)
}
}
return identityAndTrust;
}
override func didReceiveMemoryWarning() {
super .didReceiveMemoryWarning()
}
}
//定义一个结构体,存储认证相关信息
struct IdentityAndTrust {
var identityRef: SecIdentity
var trust: SecTrust
var certArray: AnyObject
}
|
控制台打印输出如下:
4,只使用一个客户端证书
由于我们使用的是自签名的证书,那么对服务器的认证全由客户端这边判断。也就是说其实使用一个客户端证书“mykey.p12”也是可以的(项目中也只需导入一个证书)。
当对服务器进行验证的时候,判断服务主机地址是否正确,是的话信任即可(代码高亮部分)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
import UIKit
import SwiftHTTP
class ViewController : UIViewController {
//自签名网站地址
let selfSignedHosts = [ "192.168.1.112" , "www.hangge.com" ]
override func viewDidLoad() {
super .viewDidLoad()
do {
let opt = try HTTP . GET ( "https://192.168.1.112:8443" )
opt.auth = { challenge in
//认证服务器(这里不使用服务器证书认证,只需地址是我们定义的几个地址即可信任)
if challenge.protectionSpace.authenticationMethod
== NSURLAuthenticationMethodServerTrust
&& self .selfSignedHosts.contains(challenge.protectionSpace.host) {
print ( "服务器认证!" )
let credential = URLCredential (trust: challenge.protectionSpace.serverTrust!)
return credential
}
//认证客户端证书
else if challenge.protectionSpace.authenticationMethod
== NSURLAuthenticationMethodClientCertificate
{
print ( "客户端证书认证!" )
//获取客户端证书相关信息
let identityAndTrust: IdentityAndTrust = self .extractIdentity();
let urlCredential: URLCredential = URLCredential (
identity: identityAndTrust.identityRef,
certificates: identityAndTrust.certArray as ? [ AnyObject ],
persistence: URLCredential . Persistence .forSession)
return urlCredential
}
// 其它情况(不接受认证)
else {
print ( "其它情况(不接受认证)" )
return nil
}
}
opt.start { response in
print ( "访问成功,获取数据如下:" )
print (response.text)
}
} catch let error {
print ( "请求失败: \(error)" )
}
}
//获取客户端证书相关信息
func extractIdentity() -> IdentityAndTrust {
var identityAndTrust: IdentityAndTrust !
var securityError: OSStatus = errSecSuccess
let path: String = Bundle .main.path(forResource: "mykey" , ofType: "p12" )!
let PKCS12Data = NSData (contentsOfFile:path)!
let key : NSString = kSecImportExportPassphrase as NSString
let options : NSDictionary = [key : "123456" ] //客户端证书密码
//create variable for holding security information
//var privateKeyRef: SecKeyRef? = nil
var items : CFArray ?
securityError = SecPKCS12Import ( PKCS12Data , options, &items)
if securityError == errSecSuccess {
let certItems: CFArray = items as CFArray !;
let certItemsArray: Array = certItems as Array
let dict: AnyObject ? = certItemsArray.first;
if let certEntry: Dictionary = dict as ? Dictionary < String , AnyObject > {
// grab the identity
let identityPointer: AnyObject ? = certEntry[ "identity" ]
let secIdentityRef: SecIdentity = identityPointer as ! SecIdentity !
print ( "\(identityPointer) :::: \(secIdentityRef)" )
// grab the trust
let trustPointer: AnyObject ? = certEntry[ "trust" ]
let trustRef: SecTrust = trustPointer as ! SecTrust
print ( "\(trustPointer) :::: \(trustRef)" )
// grab the cert
let chainPointer: AnyObject ? = certEntry[ "chain" ]
identityAndTrust = IdentityAndTrust (identityRef: secIdentityRef,
trust: trustRef, certArray: chainPointer!)
}
}
return identityAndTrust;
}
override func didReceiveMemoryWarning() {
super .didReceiveMemoryWarning()
}
}
//定义一个结构体,存储认证相关信息
struct IdentityAndTrust {
var identityRef: SecIdentity
var trust: SecTrust
var certArray: AnyObject
}
|
Swift - 使用SwiftHTTP通过HTTPS进行网络请求,及证书的使用相关推荐
- Swift - 使用Alamofire通过HTTPS进行网络请求,及证书的使用
(本文代码已升级至Swift3) 我原来写过一篇文章介绍如何使用证书通过SSL/TLS方式进行网络请求(Swift - 使用URLSession通过HTTPS进行网络请求,及证书的使用),当时用的是 ...
- 深入理解HTTPS及在iOS系统中适配HTTPS类型网络请求(上)
2019独角兽企业重金招聘Python工程师标准>>> 深入理解HTTPS及在iOS系统中适配HTTPS类型网络请求 一.引言 本篇博客主要讨论如何在客户端与服务端之间进行HTTPS ...
- Https的数据请求的证书设置
对于https的网络请求很多人都比较头疼,不止iOS包括pc端和移动端的很多请求都离不开https CFNetwork SSLHandshake failed (-9806) error = Erro ...
- HTTP HTTPS 及网络请求与响应
HTTP URI的全称为 Uniform Resource Identifier,即统一资源标志符 URL的全称为 Universal Resource Locator,即统一资源定位符 URL是UR ...
- [Swift]Alamofire使用嵌套参数进行网络请求遇到的问题
GitHub: https://github.com/Gamin-fzym/DomainManageDemo 之前封装的网络请求方法,最近发发现有些问题. /// Post请求 /// - Param ...
- 使用WeexSDK,网络请求信任证书的问题
使用0.18.0版本的weexSDK,并且是手动导入的SDK. 在项目中创建一个SDResourceRequest(名字随意)类继承WXResourceRequestHandlerDefaultImp ...
- iOS 网络请求劫持
1.概述: NSURLProtocol是URL loading system 中的一个重要的组成部分,它允许我们对全局的网络请求(基于使用URLRequest)做拦截,可拦截的请求类型有NSURLCo ...
- 二、Swift网络请求回来的数据我这样取
网络请求框架Alamofire 源码地址 Swift 2.3 Alamofire3.0版本支持 iOS 8 Swift 3 Alamofire4.0以上版本支持 iOS 9及以上系统 json数据: ...
- Swift 网络请求 Moya+RxSwift
Swift中优雅的网络请求 官方github // 1.定一个enum enum MyService {xxxxcase showUser(id: Int)xxx }// 2.扩展这个enum,符合 ...
最新文章
- R语言配对图可视化:pivot_longer函数将宽格式的数据重塑为长格式并进行数据全连接和左连接(left join)、配对图可视化(根据分类变量的值为散点图上的数据点添加颜色)
- 信息化应以电子商务为鉴——企业成长的经济共同体道路
- NTU 笔记 6422quiz 复习(1~3节)
- kali-linux nat模式下无法联网问题
- web压测工具http_load原理分析
- 数学--数论--素数
- linux屏保配置文件夹,Linux下屏保设置
- mysql基础14(关于mysql数据库在没有主键情况下去除重复数据办法)
- ORACLE 多版本读一致性
- mysql约束类型 A P_sql数据类型与约束总结
- Unity3D实践1.1:解决摄像机跟随中的视野遮挡问题
- win7升级Internet Explorer 11 先决条件更新
- JavaScript实现拖动滑块拼图验证(html5、canvas)
- 8051单片机驱动TM1620任意字符循环显示程序(详细注释版)
- 春季校园招聘简历投递量已超去年同期;亚太房地产市场现逢低买入良机 | 美通企业日报...
- 疯狂Android讲义(一)——第一部分
- idou老师教你学Istio11 : 如何用Istio实现流量熔断
- 递归解九连环并且打印中间过程
- AI最全数据集汇总:语音、歌声、音乐、图片、视频等领域开源数据集链接汇总
- 【网络】https单向认证和双向认证
热门文章
- Nginx源码分析--数据对齐posix_memalign和memalign函数
- 主成分分析(PCA)简介
- java简介 ppt 精_《JAVA》5选择结构精篇课件.ppt
- python实现单例_Python 实现单例模式
- linux命令安装组件,Linux安装各种组件
- Java项目:校园外卖点餐系统(java+SSM+JSP+maven+mysql)
- android bitmap 转drawable,android Drawable转换成Bitmap失败
- php 腾讯云实时音视频,腾讯云视频 -实时音视频学习日志
- mysql 前台启动_从Windows命令行启动MySQL
- mysql 单选字段_mysql字段类型