相关文章推荐
性感的伤疤  ·  cpu仪表盘 js - OSCHINA - ...·  1 年前    · 
豪爽的啄木鸟  ·  sparksql ...·  1 年前    · 


最近项目中用到了rsa加密解密,在此记录一下。

1.使用公钥、私钥串来加密解密

2.使用公钥der文件与私钥的p12文件来加密解密(使用p12文件解密时需要生成私钥文件时的密码)

3.下面就附上网上找的大神代码

.h文件

iOS RSA加密解密_加密解密 iOS RSA加密解密_#pragma_02

1 @interface RSA : NSObject
2
3 //使用'.der'公钥文件加密
4 + (NSString *)encryptString:(NSString *)str publicKeyWithContentsOfFile:(NSString *)path;
5
6 //使用'.12'私钥文件解密
7 + (NSString *)decryptString:(NSString *)str privateKeyWithContentsOfFile:(NSString *)path password:(NSString *)password;
8
9
10 //使用公钥字符串加密
11 + (NSString *)encryptString:(NSString *)str publicKey:(NSString *)pubKey;
12
13 //使用私钥字符串解密
14 + (NSString *)decryptString:(NSString *)str privateKey:(NSString *)privKey;
15
16 @end

查看完整代码

.m文件

iOS RSA加密解密_加密解密 iOS RSA加密解密_#pragma_02

1 #import "RSA.h"
2 #import <Security/Security.h>
3
4 @implementation RSA
5
6 static NSString *base64_encode_data(NSData *data){
7 data = [data base64EncodedDataWithOptions:0];
8 NSString *ret = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
9 return ret;
10 }
11
12 static NSData *base64_decode(NSString *str){
13 NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];
14 return data;
15 }
16
17 #pragma mark - 使用'.der'公钥文件加密
18 //加密
19 + (NSString *)encryptString:(NSString *)str publicKeyWithContentsOfFile:(NSString *)path{
20 if (!str || !path) return nil;
21 return [self encryptString:str publicKeyRef:[self getPublicKeyRefWithContentsOfFile:path]];
22 }
23
24 //获取公钥
25 + (SecKeyRef)getPublicKeyRefWithContentsOfFile:(NSString *)filePath{
26 NSData *certData = [NSData dataWithContentsOfFile:filePath];
27 if (!certData) {
28 return nil;
29 }
30 SecCertificateRef cert = SecCertificateCreateWithData(NULL, (CFDataRef)certData);
31 SecKeyRef key = NULL;
32 SecTrustRef trust = NULL;
33 SecPolicyRef policy = NULL;
34 if (cert != NULL) {
35 policy = SecPolicyCreateBasicX509();
36 if (policy) {
37 if (SecTrustCreateWithCertificates((CFTypeRef)cert, policy, &trust) == noErr) {
38 SecTrustResultType result;
39 if (SecTrustEvaluate(trust, &result) == noErr) {
40 key = SecTrustCopyPublicKey(trust);
41 }
42 }
43 }
44 }
45 if (policy) CFRelease(policy);
46 if (trust) CFRelease(trust);
47 if (cert) CFRelease(cert);
48 return key;
49 }
50
51 + (NSString *)encryptString:(NSString *)str publicKeyRef:(SecKeyRef)publicKeyRef{
52 if(![str dataUsingEncoding:NSUTF8StringEncoding]){
53 return nil;
54 }
55 if(!publicKeyRef){
56 return nil;
57 }
58 NSData *data = [self encryptData:[str dataUsingEncoding:NSUTF8StringEncoding] withKeyRef:publicKeyRef];
59 NSString *ret = base64_encode_data(data);
60 return ret;
61 }
62
63 #pragma mark - 使用'.12'私钥文件解密
64 //解密
65 + (NSString *)decryptString:(NSString *)str privateKeyWithContentsOfFile:(NSString *)path password:(NSString *)password{
66 if (!str || !path) return nil;
67 if (!password) password = @"";
68 return [self decryptString:str privateKeyRef:[self getPrivateKeyRefWithContentsOfFile:path password:password]];
69 }
70
71 //获取私钥
72 + (SecKeyRef)getPrivateKeyRefWithContentsOfFile:(NSString *)filePath password:(NSString*)password{
73
74 NSData *p12Data = [NSData dataWithContentsOfFile:filePath];
75 if (!p12Data) {
76 return nil;
77 }
78 SecKeyRef privateKeyRef = NULL;
79 NSMutableDictionary * options = [[NSMutableDictionary alloc] init];
80 [options setObject: password forKey:(__bridge id)kSecImportExportPassphrase];
81 CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
82 OSStatus securityError = SecPKCS12Import((__bridge CFDataRef) p12Data, (__bridge CFDictionaryRef)options, &items);
83 if (securityError == noErr && CFArrayGetCount(items) > 0) {
84 CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
85 SecIdentityRef identityApp = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity);
86 securityError = SecIdentityCopyPrivateKey(identityApp, &privateKeyRef);
87 if (securityError != noErr) {
88 privateKeyRef = NULL;
89 }
90 }
91 CFRelease(items);
92 return privateKeyRef;
93 }
94
95 + (NSString *)decryptString:(NSString *)str privateKeyRef:(SecKeyRef)privKeyRef{
96 NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];
97 if (!privKeyRef) {
98 return nil;
99 }
100 data = [self decryptData:data withKeyRef:privKeyRef];
101 NSString *ret = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
102 return ret;
103 }
104
105 #pragma mark - 使用公钥字符串加密
106 /* START: Encryption with RSA public key */
107
108 //使用公钥字符串加密
109 + (NSString *)encryptString:(NSString *)str publicKey:(NSString *)pubKey{
110 NSData *data = [self encryptData:[str dataUsingEncoding:NSUTF8StringEncoding] publicKey:pubKey];
111 NSString *ret = base64_encode_data(data);
112 return ret;
113 }
114
115 + (NSData *)encryptData:(NSData *)data publicKey:(NSString *)pubKey{
116 if(!data || !pubKey){
117 return nil;
118 }
119 SecKeyRef keyRef = [self addPublicKey:pubKey];
120 if(!keyRef){
121 return nil;
122 }
123 return [self encryptData:data withKeyRef:keyRef];
124 }
125
126 + (SecKeyRef)addPublicKey:(NSString *)key{
127 NSRange spos = [key rangeOfString:@"-----BEGIN PUBLIC KEY-----"];
128 NSRange epos = [key rangeOfString:@"-----END PUBLIC KEY-----"];
129 if(spos.location != NSNotFound && epos.location != NSNotFound){
130 NSUInteger s = spos.location + spos.length;
131 NSUInteger e = epos.location;
132 NSRange range = NSMakeRange(s, e-s);
133 key = [key substringWithRange:range];
134 }
135 key = [key stringByReplacingOccurrencesOfString:@"\r" withString:@""];
136 key = [key stringByReplacingOccurrencesOfString:@"\n" withString:@""];
137 key = [key stringByReplacingOccurrencesOfString:@"\t" withString:@""];
138 key = [key stringByReplacingOccurrencesOfString:@" " withString:@""];
139
140 // This will be base64 encoded, decode it.
141 NSData *data = base64_decode(key);
142 data = [self stripPublicKeyHeader:data];
143 if(!data){
144 return nil;
145 }
146
147 //a tag to read/write keychain storage
148 NSString *tag = @"RSAUtil_PubKey";
149 NSData *d_tag = [NSData dataWithBytes:[tag UTF8String] length:[tag length]];
150
151 // Delete any old lingering key with the same tag
152 NSMutableDictionary *publicKey = [[NSMutableDictionary alloc] init];
153 [publicKey setObject:(__bridge id) kSecClassKey forKey:(__bridge id)kSecClass];
154 [publicKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
155 [publicKey setObject:d_tag forKey:(__bridge id)kSecAttrApplicationTag];
156 SecItemDelete((__bridge CFDictionaryRef)publicKey);
157
158 // Add persistent version of the key to system keychain
159 [publicKey setObject:data forKey:(__bridge id)kSecValueData];
160 [publicKey setObject:(__bridge id) kSecAttrKeyClassPublic forKey:(__bridge id)
161 kSecAttrKeyClass];
162 [publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)
163 kSecReturnPersistentRef];
164
165 CFTypeRef persistKey = nil;
166 OSStatus status = SecItemAdd((__bridge CFDictionaryRef)publicKey, &persistKey);
167 if (persistKey != nil){
168 CFRelease(persistKey);
169 }
170 if ((status != noErr) && (status != errSecDuplicateItem)) {
171 return nil;
172 }
173
174 [publicKey removeObjectForKey:(__bridge id)kSecValueData];
175 [publicKey removeObjectForKey:(__bridge id)kSecReturnPersistentRef];
176 [publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];
177 [publicKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
178
179 // Now fetch the SecKeyRef version of the key
180 SecKeyRef keyRef = nil;
181 status = SecItemCopyMatching((__bridge CFDictionaryRef)publicKey, (CFTypeRef *)&keyRef);
182 if(status != noErr){
183 return nil;
184 }
185 return keyRef;
186 }
187
188 + (NSData *)stripPublicKeyHeader:(NSData *)d_key{
189 // Skip ASN.1 public key header
190 if (d_key == nil) return(nil);
191
192 unsigned long len = [d_key length];
193 if (!len) return(nil);
194
195 unsigned char *c_key = (unsigned char *)[d_key bytes];
196 unsigned int idx = 0;
197
198 if (c_key[idx++] != 0x30) return(nil);
199
200 if (c_key[idx] > 0x80) idx += c_key[idx] - 0x80 + 1;
201 else idx++;
202
203 // PKCS #1 rsaEncryption szOID_RSA_RSA
204 static unsigned char seqiod[] =
205 { 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
206 0x01, 0x05, 0x00 };
207 if (memcmp(&c_key[idx], seqiod, 15)) return(nil);
208 idx += 15;
209 if (c_key[idx++] != 0x03) return(nil);
210 if (c_key[idx] > 0x80) idx += c_key[idx] - 0x80 + 1;
211 else idx++;
212 if (c_key[idx++] != '\0') return(nil);
213 // Now make a new NSData from this buffer
214 return ([NSData dataWithBytes:&c_key[idx] length:len - idx]);
215 }
216
217 + (NSData *)encryptData:(NSData *)data withKeyRef:(SecKeyRef) keyRef{
218 const uint8_t *srcbuf = (const uint8_t *)[data bytes];
219 size_t srclen = (size_t)data.length;
220
221 size_t block_size = SecKeyGetBlockSize(keyRef) * sizeof(uint8_t);
222 void *outbuf = malloc(block_size);
223 size_t src_block_size = block_size - 11;
224
225 NSMutableData *ret = [[NSMutableData alloc] init];
226 for(int idx=0; idx<srclen; idx+=src_block_size){
227 //NSLog(@"%d/%d block_size: %d", idx, (int)srclen, (int)block_size);
228 size_t data_len = srclen - idx;
229 if(data_len > src_block_size){
230 data_len = src_block_size;
231 }
232 size_t outlen = block_size;
233 OSStatus status = noErr;
234 status = SecKeyEncrypt(keyRef,
235 kSecPaddingPKCS1,
236 srcbuf + idx,
237 data_len,
238 outbuf,
239 &outlen
240 );
241 if (status != 0) {
242 NSLog(@"SecKeyEncrypt fail. Error Code: %d", status);
243 ret = nil;
244 break;
245 }else{
246 [ret appendBytes:outbuf length:outlen];
247 }
248 }
249 free(outbuf);
250 CFRelease(keyRef);
251 return ret;
252 }
253
254
255 #pragma mark - 使用私钥字符串解密
256
257
258 //使用私钥字符串解密
259 + (NSString *)decryptString:(NSString *)str privateKey:(NSString *)privKey{
260 if (!str) return nil;
261 NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];
262 data = [self decryptData:data privateKey:privKey];
263 NSString *ret = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
264 return ret;
265 }
266
267 + (NSData *)decryptData:(NSData *)data privateKey:(NSString *)privKey{
268 if(!data || !privKey){
269 return nil;
270 }
271 SecKeyRef keyRef = [self addPrivateKey:privKey];
272 if(!keyRef){
273 return nil;
274 }
275 return [self decryptData:data withKeyRef:keyRef];
276 }
277
278 + (SecKeyRef)addPrivateKey:(NSString *)key{
279 NSRange spos = [key rangeOfString:@"-----BEGIN RSA PRIVATE KEY-----"];
280 NSRange epos = [key rangeOfString:@"-----END RSA PRIVATE KEY-----"];
281 if(spos.location != NSNotFound && epos.location != NSNotFound){
282 NSUInteger s = spos.location + spos.length;
283 NSUInteger e = epos.location;
284 NSRange range = NSMakeRange(s, e-s);
285 key = [key substringWithRange:range];
286 }
287 key = [key stringByReplacingOccurrencesOfString:@"\r" withString:@""];
288 key = [key stringByReplacingOccurrencesOfString:@"\n" withString:@""];
289 key = [key stringByReplacingOccurrencesOfString:@"\t" withString:@""];
290 key = [key stringByReplacingOccurrencesOfString:@" " withString:@""];
291
292 // This will be base64 encoded, decode it.
293 NSData *data = base64_decode(key);
294 data = [self stripPrivateKeyHeader:data];
295 if(!data){
296 return nil;
297 }
298
299 //a tag to read/write keychain storage
300 NSString *tag = @"RSAUtil_PrivKey";
301 NSData *d_tag = [NSData dataWithBytes:[tag UTF8String] length:[tag length]];
302
303 // Delete any old lingering key with the same tag
304 NSMutableDictionary *privateKey = [[NSMutableDictionary alloc] init];
305 [privateKey setObject:(__bridge id) kSecClassKey forKey:(__bridge id)kSecClass];
306 [privateKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
307 [privateKey setObject:d_tag forKey:(__bridge id)kSecAttrApplicationTag];
308 SecItemDelete((__bridge CFDictionaryRef)privateKey);
309
310 // Add persistent version of the key to system keychain
311 [privateKey setObject:data forKey:(__bridge id)kSecValueData];
312 [privateKey setObject:(__bridge id) kSecAttrKeyClassPrivate forKey:(__bridge id)
313 kSecAttrKeyClass];
314 [privateKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)
315 kSecReturnPersistentRef];
316
317 CFTypeRef persistKey = nil;
318 OSStatus status = SecItemAdd((__bridge CFDictionaryRef)privateKey, &persistKey);
319 if (persistKey != nil){
320 CFRelease(persistKey);
321 }
322 if ((status != noErr) && (status != errSecDuplicateItem)) {
323 return nil;
324 }
325 [privateKey removeObjectForKey:(__bridge id)kSecValueData];
326 [privateKey removeObjectForKey:(__bridge id)kSecReturnPersistentRef];
327 [privateKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];
328 [privateKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
329
330 // Now fetch the SecKeyRef version of the key
331 SecKeyRef keyRef = nil;
332 status = SecItemCopyMatching((__bridge CFDictionaryRef)privateKey, (CFTypeRef *)&keyRef);
333 if(status != noErr){
334 return nil;
335 }
336 return keyRef;
337 }
338
339 + (NSData *)stripPrivateKeyHeader:(NSData *)d_key{
340 // Skip ASN.1 private key header
341 if (d_key == nil) return(nil);
342
343 unsigned long len = [d_key length];
344 if (!len) return(nil);
345
346 unsigned char *c_key = (unsigned char *)[d_key bytes];
347 unsigned int idx = 22; //magic byte at offset 22
348
349 if (0x04 != c_key[idx++]) return nil;
350
351 //calculate length of the key
352 unsigned int c_len = c_key[idx++];
353 int det = c_len & 0x80;
354 if (!det) {
355 c_len = c_len & 0x7f;
356 } else {
357 int byteCount = c_len & 0x7f;
358 if (byteCount + idx > len) {
359 //rsa length field longer than buffer
360 return nil;
361 }
362 unsigned int accum = 0;
363 unsigned char *ptr = &c_key[idx];
364 idx += byteCount;
365 while (byteCount) {
366 accum = (accum << 8) + *ptr;
367 ptr++;
368 byteCount--;
369 }
370 c_len = accum;
371 }
372 // Now make a new NSData from this buffer
373 return [d_key subdataWithRange:NSMakeRange(idx, c_len)];
374 }
375
376 + (NSData *)decryptData:(NSData *)data withKeyRef:(SecKeyRef) keyRef{
377 const uint8_t *srcbuf = (const uint8_t *)[data bytes];
378 size_t srclen = (size_t)data.length;
379
380 size_t block_size = SecKeyGetBlockSize(keyRef) * sizeof(uint8_t);
381 UInt8 *outbuf = malloc(block_size);
382 size_t src_block_size = block_size;
383
384 NSMutableData *ret = [[NSMutableData alloc] init];
385 for(int idx=0; idx<srclen; idx+=src_block_size){
386 //NSLog(@"%d/%d block_size: %d", idx, (int)srclen, (int)block_size);
387 size_t data_len = srclen - idx;
388 if(data_len > src_block_size){
389 data_len = src_block_size;
390 }
391
392 size_t outlen = block_size;
393 OSStatus status = noErr;
394 status = SecKeyDecrypt(keyRef,
395 kSecPaddingNone,
396 srcbuf + idx,
397 data_len,
398 outbuf,
399 &outlen
400 );
401 if (status != 0) {
402 NSLog(@"SecKeyEncrypt fail. Error Code: %d", status);
403 ret = nil;
404 break;
405 }else{
406 //the actual decrypted data is in the middle, locate it!
407 int idxFirstZero = -1;
408 int idxNextZero = (int)outlen;
409 for ( int i = 0; i < outlen; i++ ) {
410 if ( outbuf[i] == 0 ) {
411 if ( idxFirstZero < 0 ) {
412 idxFirstZero = i;
413 } else {
414 idxNextZero = i;
415 break;
416 }
417 }
418 }
419
420 [ret appendBytes:&outbuf[idxFirstZero+1] length:idxNextZero-idxFirstZero-1];
421 }
422 }
423 free(outbuf);
424 CFRelease(keyRef);
425 return ret;
426 }
427
428 @end

查看完整代码

4.生成公钥、私钥方法请参考这篇 文章 《PHP、Android、iOS接口RSA加密解密》