Swift - 使用SwiftHTTP通过HTTPS进行网络请求,及证书的使用
来源:互联网 发布:淘宝联盟机器人发单 编辑:程序博客网 时间:2024/06/06 02:53
(本文代码已升级至Swift3)
3,使用两个证书进行双向验证,以及网络请求 控制台打印输出如下:
4,只使用一个客户端证书
由于我们使用的是自签名的证书,那么对服务器的认证全由客户端这边判断。也就是说其实使用一个客户端证书“mykey.p12”也是可以的(项目中也只需导入一个证书)。
当对服务器进行验证的时候,判断服务主机地址是否正确,是的话信任即可(代码高亮部分)
一,证书的生成,以及服务器配置
参考我前面写的这篇文章:Tomcat服务器配置https双向认证(使用keytool生成证书)
文章详细介绍了HTTPS,SSL/TLS。还有使用key tool生成自签名证书,Tomcat下https服务的配置。
二,SwiftHTTP使用HTTPS进行网络请求
1,证书导入
前面文章介绍了通过客户端浏览器访问HTTPS服务需,需要安装“mykey.p12”,“tomcat.cer”这两个证书。同样,我们开发的应用中也需要把这两个证书添加进来。
记的同时在 “工程” -> “Build Phases” -> “Copy Bundle Resources” 中添加这两个证书文件。
2,配置Info.plist
由于我们使用的是自签名的证书,而苹果ATS(App Transport Security)只信任知名CA颁发的证书,所以在iOS9下即使是HTTPS请求还是会被ATS拦截。
所以在Info.plist下添加如下配置(iOS8不需要):
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
}
0 0
- Swift - 使用SwiftHTTP通过HTTPS进行网络请求,及证书的使用
- Swift - 使用Alamofire通过HTTPS进行网络请求,及证书的使用
- SwiftHTTP的使用(译)
- 使用Swift调用AFNetworking进行网络请求
- 使用Swift调用AFNetworking进行网络请求
- swift 使用AFNetWorking 进行网络请求
- 超级简单的retrofit使用自签名证书进行HTTPS请求的教程
- 超级简单的retrofit使用自签名证书进行HTTPS请求的教程
- 使用Retrofit进行Http、Https网络请求(快速上手)
- 使用Retrofit进行Http、Https网络请求(快速上手)
- Unity 使用自己创建的certificate通过www进行https请求
- AFNetworking 使用HTTPS请求 添加证书
- iOS 开发 https问题使用AFN进行网络请求时做的一些配置
- 使用Https进行网络访问
- HTTPS进行网络请求
- iOS9 HTTPS请求: AFNetworking2安全的使用自签证书访问HTTPS
- iOS9----HTTPS 进行网络请求的解决方案
- react native 使用fetch进行网络请求(https),解决SSLHandshake问题,以及怎样进行二次封装
- 【php】冒泡排序
- JAVA高级【2.1】《Java核心技术2》XML-解析与创建
- s2第二本书第三章
- 使用MyEclipse搭建Spring+Hibernate环境
- JS:从N个数组的数据中去重后返回新数组
- Swift - 使用SwiftHTTP通过HTTPS进行网络请求,及证书的使用
- 华为Mate9导航栏遮挡PopupWindow底部布局
- CentOS7防止恶意破解root账户
- UVA Euler Circuit(混合图欧拉回路)
- 如何启动/停止/重启MySQL
- 地址
- How to setup Java Jenkins job
- 点击外部链接跳转App指定页面SingleTask模式
- JavaScript实现动态添加页面的表格行数并获取数据