示例代码,参见https://github.com/Daniate/AsymmetricEncryptionDecryption。
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
|
//
// RSASecurity.h
// AsymmetricEncryptionDecryption
//
// Created by Daniate on 14-3-18.
// Copyright (c) 2014年 Daniate. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <Security/Security.h>
#define kPublicKeyBase64 @"MIIEhjCCA26gAwIBAgIJANNrUirPXWBoMA0GCSqGSIb3DQEBBQUAMIGIMQswCQYD\
VQQGEwJDTjERMA8GA1UECBMIU2hhbmdoYWkxETAPBgNVBAcTCFNoYW5naGFpMRAw
\
DgYDVQQKEwdkYW5pYXRlMRAwDgYDVQQLEwdkYW5pYXRlMRAwDgYDVQQDEwdkYW5p
\
YXRlMR0wGwYJKoZIhvcNAQkBFg5kYW5pYXRlQHh4LmNvbTAeFw0xMjA4MDEwNjE0
\
MzVaFw0yMjA3MzAwNjE0MzVaMIGIMQswCQYDVQQGEwJDTjERMA8GA1UECBMIU2hh
\
bmdoYWkxETAPBgNVBAcTCFNoYW5naGFpMRAwDgYDVQQKEwdkYW5pYXRlMRAwDgYD
\
VQQLEwdkYW5pYXRlMRAwDgYDVQQDEwdkYW5pYXRlMR0wGwYJKoZIhvcNAQkBFg5k
\
YW5pYXRlQHh4LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKaZ
\
SdwD3CbxGmxolYL1kXHcUogwOqDnfRf8ioXoQ2RVju
/
rdtQsv23AavG4tSn5lBIA
\
hlvO6w47wQrZ8Ly2vgIMBpqTrynRrVlKPj0xSAsLT
/
P5ZQ6FFsE9PLbEOTqUcuuQ
\
PnYPURaKbhl6K8lLNR6k9wWnaU1aHoIw01pbXwYSMebiWls4c1KiGJGNOy6BVer1
\
c7Ru1gojUhNHg2UkAHE
+
VGZ3f5YOPjDEQWjypjbMk3edtvI
+
KXRZfEIG
/
p42HmXe
\
c
/
fEz2FzYEVnS
+
iFJURaMwnxuUfJ6ah9XnLsD
/
ppLczHb3KABFD
/
+
y
+
A5sksF77T
\
77FdB3Lgt1QSI77qNS0CAwEAAaOB8DCB7TAdBgNVHQ4EFgQUWr5MLDbuVpkBZRQ8
\
T8eQF2rdOlgwgb0GA1UdIwSBtTCBsoAUWr5MLDbuVpkBZRQ8T8eQF2rdOlihgY6k
\
gYswgYgxCzAJBgNVBAYTAkNOMREwDwYDVQQIEwhTaGFuZ2hhaTERMA8GA1UEBxMI
\
U2hhbmdoYWkxEDAOBgNVBAoTB2RhbmlhdGUxEDAOBgNVBAsTB2RhbmlhdGUxEDAO
\
BgNVBAMTB2RhbmlhdGUxHTAbBgkqhkiG9w0BCQEWDmRhbmlhdGVAeHguY29tggkA
\
02tSKs9dYGgwDAYDVR0TBAUwAwEB
/
zANBgkqhkiG9w0BAQUFAAOCAQEAignb7XW2
\
AlDnHhZ5UoKJ13gcyC3ELXFpEEjQbCZITQqNW3PmjB5ycm9tmpZpXJTdbj5Gvbda
\
HNjtWByu
+
DZfyjtmTYR9Os
+
WoTcj
+
QrQARHK0
+
zBEPQFRwAJGfbJShZM66
+
w
+
Q
+
N
\
9q
+
ShAiPuNoqBnckAGT7Z31e7rrUPHR7k0WK6rclXF68e
+
/
fktqgYtn2awr254Bt
\
mvVoqX3GZDe7SP5w0rV16
/
JEooH
+
7VpU13Pr883K44RbUwnXqPo5Flxxjf08h5L7
\
z
/
D6uYkB1eQt
+
bZRGApz4uFmmJnMNyCMY9
/
fByPlL4c7LxqHRQFi
/
mpaA6p4nDYs
\
7ZmPr7fSmdVEMQ
=="
typedef
NS_ENUM
(
NSUInteger
,
RSASecurityOperation
)
{
RSASecurityOperationEncrypt
=
0
,
RSASecurityOperationDecrypt
=
1
,
}
;
@interface
RSASecurity
: NSObject
@property
(
nonatomic
,
readonly
)
SecKeyRef
privateKey
;
@property
(
nonatomic
,
readonly
)
SecKeyRef
publicKey
;
+
(
RSASecurity
*
)
sharedRSASecurity
;
// Get Private Key
-
(
BOOL
)
privateKeyFromPKCS12Data
:
(
NSData
*
)
pkcs12Data
passphrase
:
(
NSString
*
)
password
;
-
(
BOOL
)
privateKeyFromPKCS12File
:
(
NSString
*
)
filePath
passphrase
:
(
NSString
*
)
password
;
// Get Public Key
-
(
BOOL
)
publicKeyFromData
:
(
NSData
*
)
data
;
-
(
BOOL
)
publicKeyFromCertificateFile
:
(
NSString
*
)
certPath
;
-
(
BOOL
)
publicKeyFromBase64EncodedString
:
(
NSString
*
)
base64EncodedString
;
// encrypt data or decrypt data
-
(
NSData
*
)
processData
:
(
NSData
*
)
inData
key
:
(
SecKeyRef
)
key
operation
:
(
RSASecurityOperation
)
operation
;
@end
|
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
|
//
// RSASecurity.m
// AsymmetricEncryptionDecryption
//
// Created by Daniate on 14-3-18.
// Copyright (c) 2014年 Daniate. All rights reserved.
//
#import "RSASecurity.h"
@implementation
RSASecurity
{
SecIdentityRef
_identity
;
SecTrustRef
_trust
;
SecKeyRef
_privateKey
;
SecKeyRef
_publicKey
;
}
static
RSASecurity
*sharedRSASecurity
=
nil
;
+
(
RSASecurity
*
)
sharedRSASecurity
{
static
dispatch_once_t
onceToken
;
dispatch_once
(
&
onceToken
,
^
{
sharedRSASecurity
=
[
[
super
allocWithZone
:NULL
]
init
]
;
}
)
;
return
sharedRSASecurity
;
}
+
(
id
)
allocWithZone
:
(
NSZone
*
)
zone
{
return
[
RSASecurity
sharedRSASecurity
]
;
}
-
(
BOOL
)
privateKeyFromPKCS12Data
:
(
NSData
*
)
pkcs12Data
passphrase
:
(
NSString
*
)
password
{
if
(
self
.
privateKey
==
NULL
)
{
OSStatus
status
=
-
1
;
SecTrustResultType
trustResultType
=
kSecTrustResultInvalid
;
if
(
pkcs12Data
)
{
const
void
*keys
[
]
=
{
kSecImportExportPassphrase
}
;
const
void
*values
[
]
=
{
(
__bridge
CFStringRef
)
password
}
;
CFDictionaryRef
options
=
CFDictionaryCreate
(
kCFAllocatorDefault
,
keys
,
values
,
1
,
NULL
,
NULL
)
;
CFArrayRef
items
=
CFArrayCreate
(
kCFAllocatorDefault
,
NULL
,
0
,
NULL
)
;
status
=
SecPKCS12Import
(
(
__bridge
CFDataRef
)
pkcs12Data
,
options
,
&
items
)
;
if
(
status
==
errSecSuccess
)
{
CFDictionaryRef
identity_trust_dic
=
CFArrayGetValueAtIndex
(
items
,
0
)
;
_identity
=
(
SecIdentityRef
)
CFDictionaryGetValue
(
identity_trust_dic
,
kSecImportItemIdentity
)
;
_trust
=
(
SecTrustRef
)
CFDictionaryGetValue
(
identity_trust_dic
,
kSecImportItemTrust
)
;
// certs数组中包含了所有的证书
CFArrayRef
certs
=
(
CFArrayRef
)
CFDictionaryGetValue
(
identity_trust_dic
,
kSecImportItemCertChain
)
;
if
(
[
(
__bridge
NSArray
*
)
certs
count
]
&&
_trust
!=
NULL
&&
_identity
!=
NULL
)
{
// 如果没有下面一句,自签名证书的评估信任结果永远是kSecTrustResultRecoverableTrustFailure
status
=
SecTrustSetAnchorCertificates
(
_trust
,
certs
)
;
if
(
status
==
errSecSuccess
)
{
// 通常, 返回的trust result type应为kSecTrustResultUnspecified,如果是,就可以说明签名证书是可信的
status
=
SecTrustEvaluate
(
_trust
,
&
trustResultType
)
;
if
(
status
==
errSecSuccess
&&
(
trustResultType
==
kSecTrustResultUnspecified
||
trustResultType
==
kSecTrustResultProceed
)
)
{
status
=
SecIdentityCopyPrivateKey
(
_identity
,
&
_privateKey
)
;
if
(
status
==
errSecSuccess
&&
self
.
privateKey
!=
NULL
)
{
// 成功提取私钥
NSLog
(
@"Get private key successfully~ %@"
,
self
.
privateKey
)
;
}
#if 0
_publicKey
=
SecTrustCopyPublicKey
(
_trust
)
;
if
(
self
.
publicKey
!=
NULL
)
{
// 成功提取公钥
NSLog
(
@"Get public key successfully~ %@"
,
self
.
publicKey
)
;
}
#endif
}
}
}
}
if
(
options
)
{
CFRelease
(
options
)
;
}
if
(
items
)
{
CFRelease
(
items
)
;
}
}
return
(
status
==
errSecSuccess
&&
(
trustResultType
==
kSecTrustResultUnspecified
||
trustResultType
==
kSecTrustResultProceed
)
)
;
}
return
YES
;
}
-
(
BOOL
)
privateKeyFromPKCS12File
:
(
NSString
*
)
filePath
passphrase
:
(
NSString
*
)
password
{
NSData
*pkcs12Data
=
[
NSData
dataWithContentsOfFile
:filePath
]
;
return
[
[
RSASecurity
sharedRSASecurity
]
privateKeyFromPKCS12Data
:pkcs12Data
passphrase
:password
]
;
}
/**
* 从指定的数据中获取公钥
*
* @param data 数据
*
* @return 是否获取成功
*/
-
(
BOOL
)
publicKeyFromData
:
(
NSData
*
)
data
{
if
(
self
.
publicKey
==
NULL
)
{
OSStatus
status
=
-
1
;
SecTrustRef
trust
=
NULL
;
SecTrustResultType
trustResult
=
kSecTrustResultInvalid
;
SecCertificateRef
cert
=
SecCertificateCreateWithData
(
kCFAllocatorDefault
,
(
__bridge
CFDataRef
)
data
)
;
SecPolicyRef
policy
=
SecPolicyCreateBasicX509
(
)
;
status
=
SecTrustCreateWithCertificates
(
cert
,
policy
,
&
trust
)
;
if
(
status
==
errSecSuccess
&&
trust
)
{
NSArray
*certs
=
[
NSArray
arrayWithObject
:
(
__bridge
id
)
cert
]
;
status
=
SecTrustSetAnchorCertificates
(
trust
,
(
__bridge
CFArrayRef
)
certs
)
;
if
(
status
==
errSecSuccess
)
{
status
=
SecTrustEvaluate
(
trust
,
&
trustResult
)
;
// 自签名证书可信
if
(
status
==
errSecSuccess
&&
(
trustResult
==
kSecTrustResultUnspecified
||
trustResult
==
kSecTrustResultProceed
)
)
{
_publicKey
=
SecTrustCopyPublicKey
(
trust
)
;
if
(
self
.
publicKey
)
{
NSLog
(
@"Get public key successfully~ %@"
,
self
.
publicKey
)
;
}
}
}
}
if
(
trust
)
{
CFRelease
(
trust
)
;
}
if
(
policy
)
{
CFRelease
(
policy
)
;
}
if
(
cert
)
{
CFRelease
(
cert
)
;
}
return
(
status
==
errSecSuccess
)
;
}
return
YES
;
}
/**
* 从证书文件中获取公钥
*
* @param certPath 证书文件路径
*
* @return 是否获取成功
*/
-
(
BOOL
)
publicKeyFromCertificateFile
:
(
NSString
*
)
certPath
{
NSData
*derData
=
[
NSData
dataWithContentsOfFile
:certPath
]
;
return
[
[
RSASecurity
sharedRSASecurity
]
publicKeyFromData
:derData
]
;
}
/**
* 从base64字符串中获取公钥
*
* @param base64EncodedString base64字符串
*
* @return 是否获取成功
*/
-
(
BOOL
)
publicKeyFromBase64EncodedString
:
(
NSString
*
)
base64EncodedString
{
NSData
*derData
=
[
[
NSData
alloc
]
initWithBase64EncodedString
:base64EncodedString
options
:NSDataBase64DecodingIgnoreUnknownCharacters
]
;
return
[
[
RSASecurity
sharedRSASecurity
]
publicKeyFromData
:derData
]
;
}
/**
* 使用指定的密钥,对密码进行相应的操作
*
* @param inData 需要处理的数据(密文/明文)
* @param key 密钥(公钥/私钥)
* @param operation 操作类型(加密/解密)
*
* @return 处理后的数据
*/
-
(
NSData
*
)
processData
:
(
NSData
*
)
inData
key
:
(
SecKeyRef
)
key
operation
:
(
RSASecurityOperation
)
operation
{
if
(
operation
!=
RSASecurityOperationEncrypt
&&
operation
!=
RSASecurityOperationDecrypt
)
{
return
nil
;
}
if
(
[
inData
length
]
==
0
)
{
return
nil
;
}
NSAssert
(
key
!=
NULL
,
@"Key must be not NULL!"
)
;
NSAssert
(
key
==
self
.
publicKey
||
key
==
self
.
privateKey
,
@"Key must be self.publicKey or self.privateKey!"
)
;
// 分配内存块,用于存放解密后的数据段
size_t
bufferSize
=
SecKeyGetBlockSize
(
key
)
;
uint8_t
*outBuffer
=
malloc
(
bufferSize
*
sizeof
(
uint8_t
)
)
;
// 计算数据段最大长度及数据段的个数
double
totalLength
=
[
inData
length
]
;
size_t
blockSize
=
bufferSize
;
if
(
operation
==
RSASecurityOperationEncrypt
)
{
size_t
min
=
11
;
// 当使用kSecPaddingPKCS1时,min必须大于等于11
blockSize
-=
min
;
}
size_t
blockCount
=
(
size_t
)
ceil
(
totalLength
/
blockSize
)
;
NSMutableData
*outData
=
[
NSMutableData
data
]
;
// 分段解密
for
(
int
i
=
0
;
i
<
blockCount
;
i
++
)
{
NSUInteger
loc
=
i
*
blockSize
;
// 数据段的实际大小。最后一段可能比blockSize小。
int
dataSegmentRealSize
=
MIN
(
blockSize
,
totalLength
-
loc
)
;
// 截取需要解密的数据段
NSData
*dataSegment
=
[
inData
subdataWithRange
:NSMakeRange
(
loc
,
dataSegmentRealSize
)
]
;
OSStatus
status
=
-
1
;
if
(
operation
==
RSASecurityOperationEncrypt
)
{
status
=
SecKeyEncrypt
(
key
,
kSecPaddingPKCS1
,
(
const
uint8_t
*
)
[
dataSegment
bytes
]
,
dataSegmentRealSize
,
outBuffer
,
&
bufferSize
)
;
}
else
if
(
operation
==
RSASecurityOperationDecrypt
)
{
status
=
SecKeyDecrypt
(
key
,
kSecPaddingPKCS1
,
(
const
uint8_t
*
)
[
dataSegment
bytes
]
,
dataSegmentRealSize
,
outBuffer
,
&
bufferSize
)
;
}
if
(
status
==
errSecSuccess
)
{
NSData
*dataSegment
=
[
[
NSData
alloc
]
initWithBytes
:
(
const
void
*
)
outBuffer
length
:bufferSize
]
;
[
outData
appendData
:dataSegment
]
;
}
else
{
if
(
outBuffer
)
{
free
(
outBuffer
)
;
}
return
nil
;
}
}
if
(
outBuffer
)
{
free
(
outBuffer
)
;
}
return
outData
;
}
@end
|