iOS常用的加密模式

2021-04-20  本文已影响0人  KingWorld

之前的项目中接触过一些加密的方法,也没有太仔细的进行记录和研究。最近在写SDK时,加密模块的占比相当之大;借此时机,对我们常用的加密方式做一个笔记。

为什么要做加密操作?
加密就是为了保证我们的数据安全,即不被他人篡改或截取到有用的信息的操作。iOS一直以安全著称,但是从XcodeGhost事件之后,iOS安全不可摧的神话似乎已经被打破。事实证明,无论是Android还是iOS,该加密处理的还是需要加密处理,谁也不能保证自己一定是安全的。下面我们来介绍iOS常用到的加密方式。

iOS常用加密方式

常见的iOS代码加密常用加密方式包括Base64加密MD5加密AES加密RSA加密等。无论选择哪种加密算法,最终都是为了保证代码安全,捍卫自己的产品原创性。

Base64加密

Base64编码的思想是:采用64个基本的ASCII码字符对数据进行重新编码。它将需要编码的数据拆分成字节数组,以3个字节为一组,按顺序排列24位数据,再把这24位数据分成4组,即每组6位;再在每组的的最高位前补两个0凑足一个字节,这样就把一个3字节为一组的数据重新编码成了4个字节;当所要编码的数据的字节数不是3的整倍数,也就是说在分组时最后一组不够3个字节,这时在最后一组填充120字节,并在最后编码完成后在结尾添加12=号。例如:将对ABC进行Base64编码首先取ABC对应的ASCII码值,A : 65B : 66C : 67,再取二进制值A : 01000001B : 01000010C : 01000011,然后把这三个字节的二进制码接起来010000010100001001000011,再以6位为单位分成4个数据块并在最高位填充两个0后形成4个字节的编码后的值00010000000101000000100100000011;再把这4个字节数据转化成10进制数1620193;最后根据Base64给出的64个基本字符表,查出对应的ASCII码字符QUJD,这里的值实际就是数据在字符表中的索引。解码过程就是把4个字节再还原成3个字节再根据不同的数据形式把字节数组重新整理成数据。注:Base64字符表,包括大写A-Z小写a-z数字0-9+以及/

Base64加密原则:6bit(原8bit)一个字节,不足的位数用0补齐,两个0用一个=表示。
Base64加密特点:


1.  `- 数据加密之后,数据量会变大,变大1/3左右。`
2.  `- 可进行反向解密。`
3.  `- 编码后有个非常显著的特点,末尾有个=号。`

在iOS中Base64加解密使用方法介绍(本例使用系统API,仅支持iOS7及以后的系统版本)

1. `/****************************Base64.m类实现文件内容****************************/`
2. `+  (NSString  *)base64EncodedStringWithData:(NSData  *)data`
3. `{`
4. `//判断是否传入需要加密数据参数`
5. `if  ((data ==  nil)  ||  (data ==  NULL))  {`
6. `return  nil;`
7. `}  else  if  (![data isKindOfClass:[NSData  class]])  {`
8. `return  nil;`
9. `}`
10. `//判断设备系统是否满足条件`
11. `if  ([[[UIDevice currentDevice] systemVersion] doubleValue]  <=  6.9)  {`
12. `return  nil;`
13. `}`
14. `//使用系统的API进行Base64加密操作`
15. `NSDataBase64EncodingOptions options;`
16. `options =  NSDataBase64EncodingEndLineWithLineFeed;`
17. `return  [data base64EncodedStringWithOptions:options];`
18. `}`
19. `+  (NSData  *)base64DecodeDataWithString:(NSString  *)string`
20. `{`
21. `//判断是否传入需要加密数据参数`
22. `if  ((string  ==  nil)  ||  (string  ==  NULL))  {`
23. `return  nil;`
24. `}  else  if  (![string isKindOfClass:[NSString  class]])  {`
25. `return  nil;`
26. `}`
27. `//判断设备系统是否满足条件`
28. `if  ([[[UIDevice currentDevice] systemVersion] doubleValue]  <=  6.9)  {`
29. `return  nil;`
30. `}`
31. `//使用系统的API进行Base64解密操作`
32. `NSDataBase64DecodingOptions options;`
33. `options =  NSDataBase64DecodingIgnoreUnknownCharacters;`
34. `return  [[NSData alloc] initWithBase64EncodedString:string options:options];`
35. `}`
36. `/*****************************************************************************/`
37. `//使用Base64文件进行Base64加密和解密`
38. `/*********************************使用Base64类*********************************/`
39. `//使用Base64执行加密操作`
40. `NSString  *string  =  @"abcdefghijklmnopqrstuvwxyz";`
41. `NSData  *data =  [string dataUsingEncoding:NSUTF8StringEncoding];`
42. `NSString  *encodeString =  [Base64 base64EncodedStringWithData:data];`
43. `NSLog(@"encodeString : %@", encodeString);`
44. `//使用Base64执行解密操作`
45. `NSString  *decodeString =  nil;`
46. `NSData  *decodeData =  [Base64 base64DecodeDataWithString:encodeString];`
47. `decodeString =  [[NSString alloc] initWithData:decodeData`
48. `encoding:NSUTF8StringEncoding];`
49. `NSLog(@"decodeString : %@", decodeString);`
50. `/******************************************************************************/`

MD5加密(MD5是一种摘要,而非加密,只是经常与加密配合使用)

MD5的全称是Message-DigestAlgorithm 5Message-Digest泛指字节串(Message)的Hash变换,就是把一个任意长度的字节串变换成一定长的大整数。请注意我使用了字节串而不是字符串这个词,是因为这种变换只与字节的值有关,与字符集或编码方式无关。MD5将任意长度的字节串变换成一个128bit的大整数,并且它是一个不可逆的字符串变换算法,换句话说就是,即使你看到源程序和算法描述,也无法将一个MD5的值变换回原始的字符串,从数学原理上说,是因为原始的字符串有无穷多个,这有点象不存在反函数的数学函数。MD5的典型应用是对一段Message(字节串)产生fingerprint(指纹),以防止被”篡改”。举个例子,你将一段话写在一个叫readme.txt文件中,并对这个readme.txt产生一个MD5的值并记录在案,然后你可以传播这个文件给别人,别人如果修改了文件中的任何内容,你对这个文件重新计算MD5时就会发现。如果再有一个第三方的认证机构,用MD5还可以防止文件作者的”抵赖”,这就是所谓的数字签名应用。MD5还广泛用于加密和解密技术上,在很多操作系统中,用户的密码是以MD5值(或类似的其它算法)的方式保存的,用户Login的时候,系统是把用户输入的密码计算成MD5值,然后再去和系统中保存的MD5值进行比较,而系统并”不知道”用户的密码是什么。MD5加密大体都应用在:验证数据或文件一致性、数字签名、安全访问认证等等。大概可比喻为:人的指纹来理解。
注:MD5加密是不可逆的,也就是说,MD5加密后是不能解密的,所谓的解密只是用大数据的”试用”,来测出结果的。

MD5特点:

1.  `- 压缩性  :  任意长度的数据,算出的MD5值长度都是固定的。`
2.  `- 容易计算  :  从原数据计算出MD5值很容易。`
3.  `- 抗修改性  :  对原数据进行任何改动,哪怕只修改一个字节,所得到的MD5值都有很大区别。`
4.  `- 弱抗碰撞  :  已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。`
5.  `- 强抗碰撞  :  想找到两个不同数据,使他们具有相同的MD5值,是非常困难的。`

在iOS中MD5加密和验签使用方法介绍


1.  `/****************************MD5.m类实现文件内容****************************/`
2.  `//对字符串数据进行MD5的签名`
3.  `+  (NSString  *)md5SignWithString:(NSString  *)string`
4.  `{`
5.  `const  char  *object  =  [string UTF8String];`
6.  `unsigned  char result[CC_MD5_DIGEST_LENGTH];`
7.  `CC_MD5(object,(CC_LONG)strlen(object),result);`
8.  `NSMutableString  *hash =  [NSMutableString  string];`
9.  `for  (int i =  0; i <  16; i ++)  {`
10.  `[hash appendFormat:@"%02X", result[i]];`
11.  `}`
12.  `return  [hash lowercaseString];`
13.  `}`
14.  `//对二进制数据进行MD5的签名`
15.  `+  (NSData  *)md5SignWithData:(NSData  *)data`
16.  `{`
17.  `Byte  byte[CC_MD5_DIGEST_LENGTH];  //定义一个字节数组来接收结果`
18.  `CC_MD5((const  void*)([data bytes]),  (CC_LONG)[data length],  byte);`
19.  `return  [NSData dataWithBytes:byte length:CC_MD5_DIGEST_LENGTH];`
20.  `}`
21.  `/******************************************************************************/`
22.  `//使用MD5文件进行MD5加密和验签`
23.  `/*********************************使用MD5类*********************************/`
24.  `//使用MD5执行加密操作`
25.  `NSString  *string2 =  @"abcdefghijklmnopqrstuvwxyz";`
26.  `NSString  *encodeString2 =  [MD5 md5SignWithString:string2];`
27.  `NSLog(@"encodeString2 : %@", encodeString2);`
28.  `//MD5为不可逆的操作,使用MD5执行验签操作`
29.  `NSString  *verifyString2 =  [MD5 md5SignWithString:string2];`
30.  `NSLog(@"verifyString2 : %@", verifyString2);`
31.  `if  ([verifyString2 isEqualToString:encodeString2])  {`
32.  `NSLog(@"md5 verify sign success");`
33.  `}  else  {`
34.  `NSLog(@"md5 verify sign failed");`
35.  `}`
36.  `/******************************************************************************/`

AES加密

高级加密标准Advanced Encryption Standard简称:AES,在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。它是一种对称加密算法,这个标准也替代原先的DES标准,已经被多方分析且广为全世界所使用。AES设计有三个密钥长度:128、192、256位,相对而言,AES的128密钥比DES的56密钥强1021倍。AES算法主要包括三个方面:轮变化、圈数和密钥扩展。总体来说,AES作为新一代的数据加密标准汇聚了强安全性、高性能、高效率、易用和灵活,在软件及硬件上都能快速地加解密且只需要很少的存储资源等优点。

AES加密流程介绍无从下笔,直接上图了。

image

AES加解密特点:


1.  `- AES强安全性、高性能、高效率、易用和灵活。`
2.  `- 在软件及硬件上都能快速地加解密且只需要很少的存储资源。`

在iOS中AES加解密的实现介绍


1.  `//需要导入:#import <CommonCrypto/CommonCrypto.h>库才能使用`
2.  `/**`
3.  `*  AES128 + ECB + PKCS7`
4.  `*  @param data 要加密的原始数据`
5.  `*  @param key  加密 key`
6.  `*  @return  加密后数据`
7.  `*/`
8.  `+  (NSData  *)encryptData:(NSData  *)data key:(NSData  *)key`
9.  `{`
10.  `//判断解密的流数据是否存在`
11.  `if  ((data ==  nil)  ||  (data ==  NULL))  {`
12.  `return  nil;`
13.  `}  else  if  (![data isKindOfClass:[NSData  class]])  {`
14.  `return  nil;`
15.  `}  else  if  ([data length]  <=  0)  {`
16.  `return  nil;`
17.  `}`
18.  `//判断解密的Key是否存在`
19.  `if  ((key ==  nil)  ||  (key ==  NULL))  {`
20.  `return  nil;`
21.  `}  else  if  (![key isKindOfClass:[NSData  class]])  {`
22.  `return  nil;`
23.  `}  else  if  ([key length]  <=  0)  {`
24.  `return  nil;`
25.  `}`
26.  `//setup key`
27.  `NSData  *result =  nil;`
28.  `unsigned  char cKey[kCCKeySizeAES128];`
29.  `bzero(cKey,  sizeof(cKey));`
30.  `[key getBytes:cKey length:kCCKeySizeAES128];`
31.  `//setup output buffer`
32.  `size_t bufferSize =  [data length]  + kCCBlockSizeAES128;`
33.  `void  *buffer = malloc(bufferSize);`
34.  `//do encrypt`
35.  `size_t encryptedSize =  0;`
36.  `CCCryptorStatus cryptStatus =  CCCrypt(kCCEncrypt,`
37.  `kCCAlgorithmAES128,`
38.  `kCCOptionECBMode|kCCOptionPKCS7Padding,`
39.  `cKey,`
40.  `kCCKeySizeAES128,`
41.  `nil,`
42.  `[data bytes],`
43.  `[data length],`
44.  `buffer,`
45.  `bufferSize,`
46.  `&encryptedSize);`
47.  `if  (cryptStatus == kCCSuccess)  {`
48.  `result =  [NSData dataWithBytesNoCopy:buffer length:encryptedSize];`
49.  `}  else  {`
50.  `free(buffer);`
51.  `}`
52.  `return result;`
53.  `}`
54.  `/**`
55.  `*  AES128 + ECB + PKCS7`
56.  `*  @param data 要解密的原始数据`
57.  `*  @param key  解密 key`
58.  `*  @return  解密后数据`
59.  `*/`
60.  `+  (NSData  *)decryptData:(NSData  *)data key:(NSData  *)key`
61.  `{`
62.  `//判断解密的流数据是否存在`
63.  `if  ((data ==  nil)  ||  (data ==  NULL))  {`
64.  `return  nil;`
65.  `}  else  if  (![data isKindOfClass:[NSData  class]])  {`
66.  `return  nil;`
67.  `}  else  if  ([data length]  <=  0)  {`
68.  `return  nil;`
69.  `}`
70.  `//判断解密的Key是否存在`
71.  `if  ((key ==  nil)  ||  (key ==  NULL))  {`
72.  `return  nil;`
73.  `}  else  if  (![key isKindOfClass:[NSData  class]])  {`
74.  `return  nil;`
75.  `}  else  if  ([key length]  <=  0)  {`
76.  `return  nil;`
77.  `}`
78.  `//setup key`
79.  `NSData  *result =  nil;`
80.  `unsigned  char cKey[kCCKeySizeAES128];`
81.  `bzero(cKey,  sizeof(cKey));`
82.  `[key getBytes:cKey length:kCCKeySizeAES128];`
83.  `//setup output buffer`
84.  `size_t bufferSize =  [data length]  + kCCBlockSizeAES128;`
85.  `void  *buffer = malloc(bufferSize);`
86.  `//do decrypt`
87.  `size_t decryptedSize =  0;`
88.  `CCCryptorStatus cryptStatus =  CCCrypt(kCCDecrypt,`
89.  `kCCAlgorithmAES128,`
90.  `kCCOptionECBMode|kCCOptionPKCS7Padding,`
91.  `cKey,`
92.  `kCCKeySizeAES128,`
93.  `nil,`
94.  `[data bytes],`
95.  `[data length],`
96.  `buffer,`
97.  `bufferSize,`
98.  `&decryptedSize);`
99.  `if  (cryptStatus == kCCSuccess)  {`
100.  `result =  [NSData dataWithBytesNoCopy:buffer length:decryptedSize];`
101.  `}  else  {`
102.  `free(buffer);`
103.  `}`
104.  `return result;`
105.  `}`

在iOS中AES加解密使用方法介绍


1.  `//使用AES执行加密操作`
2.  `NSString  *aesKey =  @"a1b2c3d4e5f6g7h8";`
3.  `NSString  *string3 =  @"abcdefghijklmnopqrstuvwxyz";`
4.  `NSData  *keyData3 =  [aesKey dataUsingEncoding:NSUTF8StringEncoding];`
5.  `NSData  *sourceData3 =  [string3 dataUsingEncoding:NSUTF8StringEncoding];`
6.  `NSData  *encodeData3 =  [AESEncrypt encryptData:sourceData3 key:keyData3];`
7.  `NSLog(@"encodeData3 : %@", encodeData3);`
8.  `//使用AES执行解密操作`
9.  `NSString  *decodeString3 =  nil;`
10.  `NSData  *decodeData3 =  [AESEncrypt decryptData:encodeData3`
11.  `key:keyData3];`
12.  `decodeString3 =  [[NSString alloc] initWithData:decodeData3`
13.  `encoding:NSUTF8StringEncoding];`
14.  `NSLog(@"decodeString3 : %@", decodeString3);`

RSA加密

RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。RSA的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。通常是先生成一对RSA密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。为提高保密强度,RSA密钥至少为500位长,一般推荐使用1024位,这就使加密的计算量很大。为减少计算量,在传送信息时,常采用传统加密方法与公开密钥加密方法相结合的方式,即信息采用改进的DES或IDEA对话密钥加密,然后使用RSA密钥加密对话密钥和信息摘要,对方收到信息后,用不同的密钥解密并可核对信息摘要。RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作,RSA是被研究得最广泛的公钥算法。RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。RSA加密大体都应用在:本地数据加密、网络传输数据加密、方法体和方法名高级混淆以及程序结构混排加密。例如:对客户端传输数据提供加密方案,有效防止通过网络接口的拦截获取。

RSA的算法涉及三个参数,n、e1、e2。其中,n是两个大质数p、q的积,n的二进制表示时所占用的位数,就是所谓的密钥长度。e1和e2是一对相关的值,e1可以任意取,但要求e1与(p-1)(q-1)互质;再选择e2,要求(e2e1)mod((p-1)*(q-1))=1。(n,e1),(n,e2)就是密钥对。其中(n,e1)为公钥,(n,e2)为私钥;RSA加解密的算法完全相同,公钥加密体制中,一般用公钥加密,私钥解密。假设A为明文,B为密文,则:A=B^e2 mod n;B=A^e1 mod n;e1和e2可以互换使用,即私钥加密,公钥解密,公式:A=B^e1 mod n;B=A^e2 mod n;

RSA加解密特点:


1.  `- RSA密钥管理的方便,计算量很大速度相对比较慢。`
2.  `- RSA安全性很高,能够抵抗到目前为止已知的绝大多数密码攻击。`

在线生成RSA密钥对的网址:在线生成非对称加密公钥私钥对等,RSA密钥格式请使用PKCS#8格式。PKCS#1与PKCS#8的区别还待后续查阅资料,再进行补充记录。

在iOS中RSA加解密的实现介绍(支持密钥文件<.pem>和字符串密钥)


1.  `/****************************RSAEncrypt.m类实现文件内容****************************/`
2.  `pragma mark -  Class  Utils  Method`
3.  `+  (BOOL)isEmptyKeyRef:(id)object`
4.  `{`
5.  `if  (object  ==  nil)  {`
6.  `return YES;`
7.  `}  else  if  (object  == NULL)  {`
8.  `return YES;`
9.  `}  else  if  (object  ==  [NSNull  null])  {`
10.  `return YES;`
11.  `}`
12.  `return NO;`
13.  `}`
14.  `pragma mark -  Private  Method`
15.  `+  (SecKeyRef)getPrivateKeyRefWithFilePath:(NSString  *)filePath keyPassword:(NSString  *)keyPassword`
16.  `{`
17.  `//读取私钥证书文件的内容`
18.  `NSData  *certificateData =  [NSData dataWithContentsOfFile:filePath];`
19.  `if  ((certificateData ==  nil)  ||  (certificateData == NULL))  {`
20.  `return  nil;`
21.  `}  else  if  (![certificateData isKindOfClass:[NSData  class]])  {`
22.  `return  nil;`
23.  `}  else  if  ([certificateData length]  <=  0)  {`
24.  `return  nil;`
25.  `}`
26.  `//拼接密码参数到字典中`
27.  `NSString  *passwordKey =  (__bridge id)kSecImportExportPassphrase;`
28.  `NSString  *passwordValue =  [NSString stringWithFormat:@"%@",keyPassword];`
29.  `if  ((keyPassword ==  nil)  ||  (keyPassword == NULL))  {`
30.  `passwordValue =  @"";`
31.  `}  else  if  (![keyPassword isKindOfClass:[NSString  class]])  {`
32.  `passwordValue =  @"";`
33.  `}  else  if  ([keyPassword length]  <=  0)  {`
34.  `passwordValue =  @"";`
35.  `}`
36.  `NSMutableDictionary  *optionInfo =  [[NSMutableDictionary alloc] init];`
37.  `[optionInfo setObject:passwordValue forKey:passwordKey];`
38.  `//获取私钥对象`
39.  `SecKeyRef privateKeyRef = NULL;`
40.  `CFArrayRef items =  CFArrayCreate(NULL,  0,  0, NULL);`
41.  `CFDataRef pkcs12Data =  (__bridge CFDataRef)certificateData;`
42.  `CFDictionaryRef options =  (__bridge CFDictionaryRef)optionInfo;`
43.  `OSStatus securityStatus =  SecPKCS12Import(pkcs12Data, options,  &items);`
44.  `if  (securityStatus == noErr &&  CFArrayGetCount(items)  >  0)`
45.  `{`
46.  `SecIdentityRef identity;`
47.  `const  void  *secpkey = kSecImportItemIdentity;`
48.  `CFDictionaryRef identityDict =  CFArrayGetValueAtIndex(items,  0);`
49.  `identity =  (SecIdentityRef)CFDictionaryGetValue(identityDict,secpkey);`
50.  `securityStatus =  SecIdentityCopyPrivateKey(identity,  &privateKeyRef);`
51.  `if  (securityStatus != noErr)`
52.  `{`
53.  `privateKeyRef = NULL;`
54.  `}`
55.  `}`
56.  `CFRelease(items);`
57.  `return privateKeyRef;`
58.  `}`
59.  `+  (SecKeyRef)privateKeyRefWithPrivateKey:(NSString  *)privateKey`
60.  `{`
61.  `//判断参数是否正确`
62.  `if  ((privateKey ==  nil)  ||  (privateKey == NULL))  {`
63.  `return  nil;`
64.  `}  else  if  (![privateKey isKindOfClass:[NSString  class]])  {`
65.  `return  nil;`
66.  `}  else  if  ([privateKey length]  <=  0)  {`
67.  `return  nil;`
68.  `}`
69.  `//解析私钥对象内容`
70.  `NSString  *pKey =  [NSString stringWithFormat:@"%@",privateKey];`
71.  `NSRange sposition =  [pKey rangeOfString:@"-----BEGIN RSA PRIVATE KEY-----"];`
72.  `NSRange eposition =  [pKey rangeOfString:@"-----END RSA PRIVATE KEY-----"];`
73.  `if  (sposition.location !=  NSNotFound  && eposition.location !=  NSNotFound)`
74.  `{`
75.  `NSUInteger endposition = eposition.location;`
76.  `NSUInteger startposition = sposition.location + sposition.length;`
77.  `NSRange range =  NSMakeRange(startposition, endposition-startposition);`
78.  `pKey =  [pKey substringWithRange:range];`
79.  `}`
80.  `pKey =  [pKey stringByReplacingOccurrencesOfString:@"r" withString:@""];`
81.  `pKey =  [pKey stringByReplacingOccurrencesOfString:@"n" withString:@""];`
82.  `pKey =  [pKey stringByReplacingOccurrencesOfString:@"t" withString:@""];`
83.  `pKey =  [pKey stringByReplacingOccurrencesOfString:@" " withString:@""];`
84.  `//This will be base64 encoded, decode it.`
85.  `NSData  *keyData =  [Base64 base64DecodeDataWithString:pKey];`
86.  `keyData =  [self stripPrivateKeyHeader:keyData];`
87.  `if  ((keyData ==  nil)  ||  (keyData == NULL))  {`
88.  `return  nil;`
89.  `}  else  if  (![keyData isKindOfClass:[NSData  class]])  {`
90.  `return  nil;`
91.  `}  else  if  ([keyData length]  <=  0)  {`
92.  `return  nil;`
93.  `}`
94.  `//a tag to read/write keychain storage`
95.  `NSString  *tag =  @"RSAUtil_PrivKey";`
96.  `const  void  *bytes =  [tag UTF8String];`
97.  `NSData  *tagData =  [NSData dataWithBytes:bytes length:[tag length]];`
98.  `//Delete any old lingering key with the same tag`
99.  `NSMutableDictionary  *attributes =  [[NSMutableDictionary alloc] init];`
100.  `[attributes setObject:(__bridge id)kSecClassKey`
101.  `forKey:(__bridge id)kSecClass];`
102.  `[attributes setObject:(__bridge id)kSecAttrKeyTypeRSA`
103.  `forKey:(__bridge id)kSecAttrKeyType];`
104.  `[attributes setObject:tagData`
105.  `forKey:(__bridge id)kSecAttrApplicationTag];`
106.  `SecItemDelete((__bridge CFDictionaryRef)attributes);`
107.  `//Add persistent version of the key to system keychain`
108.  `[attributes setObject:keyData forKey:(__bridge id)kSecValueData];`
109.  `[attributes setObject:(__bridge id)kSecAttrKeyClassPrivate`
110.  `forKey:(__bridge id)kSecAttrKeyClass];`
111.  `[attributes setObject:[NSNumber numberWithBool:YES]`
112.  `forKey:(__bridge id)kSecReturnPersistentRef];`
113.  `OSStatus status = noErr;`
114.  `CFTypeRef persistKey =  nil;`
115.  `status =  SecItemAdd((__bridge CFDictionaryRef)attributes,  &persistKey);`
116.  `if  (persistKey !=  nil)  {CFRelease(persistKey);}`
117.  `if  ((status != noErr)  &&  (status != errSecDuplicateItem))`
118.  `{`
119.  `return  nil;`
120.  `}`
121.  `[attributes removeObjectForKey:(__bridge id)kSecValueData];`
122.  `[attributes removeObjectForKey:(__bridge id)kSecReturnPersistentRef];`
123.  `[attributes setObject:[NSNumber numberWithBool:YES]`
124.  `forKey:(__bridge id)kSecReturnRef];`
125.  `[attributes setObject:(__bridge id)kSecAttrKeyTypeRSA`
126.  `forKey:(__bridge id)kSecAttrKeyType];`
127.  `//Now fetch the SecKeyRef version of the key`
128.  `SecKeyRef keyRef =  nil;`
129.  `CFDictionaryRef query =  (__bridge CFDictionaryRef)attributes;`
130.  `status =  SecItemCopyMatching(query,  (CFTypeRef  *)&keyRef);`
131.  `if  (status != noErr)`
132.  `{`
133.  `return  nil;`
134.  `}`
135.  `return keyRef;`
136.  `}`
137.  `+  (NSData  *)stripPrivateKeyHeader:(NSData  *)d_key`
138.  `{`
139.  `//Skip ASN.1 private key header`
140.  `if  (d_key ==  nil)  return  nil;`
141.  `unsigned  long len =  [d_key length];`
142.  `if  (!len)  return  nil;`
143.  `unsigned  char  *c_key =  (unsigned  char  *)[d_key bytes];`
144.  `unsigned  int idx =  22;  //magic byte at offset 22`
145.  `if  (0x04  != c_key[idx++])  return  nil;`
146.  `//calculate length of the key`
147.  `unsigned  int c_len = c_key[idx++];`
148.  `if  (!(c_len &  0x80))`
149.  `{`
150.  `c_len = c_len &  0x7f;`
151.  `}`
152.  `else`
153.  `{`
154.  `int byteCount = c_len &  0x7f;`
155.  `if  (byteCount + idx > len)  {`
156.  `//rsa length field longer than buffer`
157.  `return  nil;`
158.  `}`
159.  `unsigned  int accum =  0;`
160.  `unsigned  char  *ptr =  &c_key[idx];`
161.  `idx += byteCount;`
162.  `while  (byteCount)  {`
163.  `accum =  (accum <<  8)  +  *ptr;`
164.  `ptr++;`
165.  `byteCount--;`
166.  `}`
167.  `c_len = accum;`
168.  `}`
169.  `//Now make a new NSData from this buffer`
170.  `return  [d_key subdataWithRange:NSMakeRange(idx, c_len)];`
171.  `}`
172.  `+  (SecKeyRef)getPublicKeyRefWithFilePath:(NSString  *)filePath`
173.  `{`
174.  `//读取公钥证书文件的内容`
175.  `NSData  *certificateData =  [NSData dataWithContentsOfFile:filePath];`
176.  `if  ((certificateData ==  nil)  ||  (certificateData == NULL))  {`
177.  `return  nil;`
178.  `}  else  if  (![certificateData isKindOfClass:[NSData  class]])  {`
179.  `return  nil;`
180.  `}  else  if  ([certificateData length]  <=  0)  {`
181.  `return  nil;`
182.  `}`
183.  `//将公钥证书制作成证书对象`
184.  `CFDataRef data =  (__bridge CFDataRef)certificateData;`
185.  `SecCertificateRef certificateRef =  SecCertificateCreateWithData(NULL, data);`
186.  `//获取公钥对象`
187.  `SecTrustRef trust = NULL;`
188.  `SecKeyRef publicKey = NULL;`
189.  `SecPolicyRef policies =  SecPolicyCreateBasicX509();`
190.  `if  (![[self  class] isEmptyKeyRef:(__bridge id)(certificateRef)]`
191.  `&&  ![[self  class] isEmptyKeyRef:(__bridge id)(policies)])`
192.  `{`
193.  `OSStatus status;`
194.  `status =  SecTrustCreateWithCertificates((CFTypeRef)certificateRef,`
195.  `policies,  &trust);`
196.  `if  (status == noErr)`
197.  `{`
198.  `SecTrustResultType result;`
199.  `if  (SecTrustEvaluate(trust,  &result)  == noErr)`
200.  `{`
201.  `publicKey =  SecTrustCopyPublicKey(trust);`
202.  `}`
203.  `}`
204.  `}`
205.  `if  (certificateRef != NULL)  CFRelease(certificateRef);`
206.  `if  (policies != NULL)  CFRelease(policies);`
207.  `if  (trust != NULL)  CFRelease(trust);`
208.  `return publicKey;`
209.  `}`
210.  `+  (SecKeyRef)publicKeyRefWithPublicKey:(NSString  *)publicKey`
211.  `{`
212.  `//判断参数是否正确`
213.  `if  ((publicKey ==  nil)  ||  (publicKey == NULL))  {`
214.  `return  nil;`
215.  `}  else  if  (![publicKey isKindOfClass:[NSString  class]])  {`
216.  `return  nil;`
217.  `}  else  if  ([publicKey length]  <=  0)  {`
218.  `return  nil;`
219.  `}`
220.  `//解析公钥对象内容`
221.  `NSString  *pKey =  [NSString stringWithFormat:@"%@",publicKey];`
222.  `NSRange sposition =  [pKey rangeOfString:@"-----BEGIN PUBLIC KEY-----"];`
223.  `NSRange eposition =  [pKey rangeOfString:@"-----END PUBLIC KEY-----"];`
224.  `if  (sposition.location !=  NSNotFound  && eposition.location !=  NSNotFound)`
225.  `{`
226.  `NSUInteger startposition = eposition.location;`
227.  `NSUInteger endposition = sposition.location + sposition.length;`
228.  `NSRange range =  NSMakeRange(endposition, startposition-endposition);`
229.  `pKey =  [pKey substringWithRange:range];`
230.  `}`
231.  `pKey =  [pKey stringByReplacingOccurrencesOfString:@"r" withString:@""];`
232.  `pKey =  [pKey stringByReplacingOccurrencesOfString:@"n" withString:@""];`
233.  `pKey =  [pKey stringByReplacingOccurrencesOfString:@"t" withString:@""];`
234.  `pKey =  [pKey stringByReplacingOccurrencesOfString:@" " withString:@""];`
235.  `//This will be base64 encoded, decode it.`
236.  `NSData  *keyData =  [[self  class] base64DecodeDataWithString:pKey];`
237.  `keyData =  [self stripPublicKeyHeader:keyData];`
238.  `if  ((keyData ==  nil)  ||  (keyData == NULL))  {`
239.  `return  nil;`
240.  `}  else  if  (![keyData isKindOfClass:[NSData  class]])  {`
241.  `return  nil;`
242.  `}  else  if  ([keyData length]  <=  0)  {`
243.  `return  nil;`
244.  `}`
245.  `//a tag to read/write keychain storage`
246.  `NSString  *tag =  @"RSAUtil_PubKey";`
247.  `const  void  *bytes =  [tag UTF8String];`
248.  `NSData  *tagData =  [NSData dataWithBytes:bytes length:[tag length]];`
249.  `//Delete any old lingering key with the same tag`
250.  `NSMutableDictionary  *attributes =  [[NSMutableDictionary alloc] init];`
251.  `[attributes setObject:(__bridge id)kSecClassKey`
252.  `forKey:(__bridge id)kSecClass];`
253.  `[attributes setObject:(__bridge id)kSecAttrKeyTypeRSA`
254.  `forKey:(__bridge id)kSecAttrKeyType];`
255.  `[attributes setObject:tagData`
256.  `forKey:(__bridge id)kSecAttrApplicationTag];`
257.  `SecItemDelete((__bridge CFDictionaryRef)attributes);`
258.  `//Add persistent version of the key to system keychain`
259.  `[attributes setObject:keyData`
260.  `forKey:(__bridge id)kSecValueData];`
261.  `[attributes setObject:(__bridge id)kSecAttrKeyClassPublic`
262.  `forKey:(__bridge id)kSecAttrKeyClass];`
263.  `[attributes setObject:[NSNumber numberWithBool:YES]`
264.  `forKey:(__bridge id)kSecReturnPersistentRef];`
265.  `OSStatus status = noErr;`
266.  `CFTypeRef persistKey =  nil;`
267.  `status =  SecItemAdd((__bridge CFDictionaryRef)attributes,  &persistKey);`
268.  `if  (persistKey !=  nil)  CFRelease(persistKey);`
269.  `if  ((status != noErr)  &&  (status != errSecDuplicateItem))`
270.  `{`
271.  `return  nil;`
272.  `}`
273.  `[attributes removeObjectForKey:(__bridge id)kSecValueData];`
274.  `[attributes removeObjectForKey:(__bridge id)kSecReturnPersistentRef];`
275.  `[attributes setObject:[NSNumber numberWithBool:YES]`
276.  `forKey:(__bridge id)kSecReturnRef];`
277.  `[attributes setObject:(__bridge id)kSecAttrKeyTypeRSA`
278.  `forKey:(__bridge id)kSecAttrKeyType];`
279.  `//Now fetch the SecKeyRef version of the key`
280.  `SecKeyRef publicKeyRef =  nil;`
281.  `CFDictionaryRef query =  (__bridge CFDictionaryRef)attributes;`
282.  `status =  SecItemCopyMatching(query,  (CFTypeRef  *)&publicKeyRef);`
283.  `if  (status != noErr)`
284.  `{`
285.  `return  nil;`
286.  `}`
287.  `return publicKeyRef;`
288.  `}`
289.  `+  (NSData  *)stripPublicKeyHeader:(NSData  *)d_key`
290.  `{`
291.  `//Skip ASN.1 public key header`
292.  `if  (d_key ==  nil)  {return  nil;}`
293.  `unsigned  long len =  [d_key length];`
294.  `if  (!len)  return(nil);`
295.  `unsigned  char  *c_key =  (unsigned  char  *)[d_key bytes];`
296.  `unsigned  int idx =  0;`
297.  `if  (c_key[idx++]  !=  0x30)  {return  nil;}`
298.  `if  (c_key[idx]  >  0x80)`
299.  `{`
300.  `idx += c_key[idx]  -  0x80  +  1;`
301.  `}`
302.  `else`
303.  `{`
304.  `idx++;`
305.  `}`
306.  `//PKCS #1 rsaEncryption szOID_RSA_RSA`
307.  `static  unsigned  char seqiod[]  =  {0x30,  0x0d,  0x06,  0x09,  0x2a,`
308.  `0x86,  0x48,  0x86,  0xf7,  0x0d,`
309.  `0x01,  0x01,  0x01,  0x05,  0x00};`
310.  `if  (memcmp(&c_key[idx], seqiod,  15))  {return  nil;}`
311.  `idx +=  15;`
312.  `if  (c_key[idx++]  !=  0x03)  {return  nil;}`
313.  `if  (c_key[idx]  >  0x80)`
314.  `{`
315.  `idx += c_key[idx]  -  0x80  +  1;`
316.  `}`
317.  `else`
318.  `{`
319.  `idx ++;`
320.  `}`
321.  `if  (c_key[idx++]  !=  '')  {return  nil;}`
322.  `//Now make a new NSData from this buffer`
323.  `return  ([NSData dataWithBytes:&c_key[idx] length:len - idx]);`
324.  `}`
325.  `+  (NSData  *)encryptData:(NSData  *)data withKeyRef:(SecKeyRef)keyRef`
326.  `{`
327.  `const  uint8_t  *srcbuf =  (const  uint8_t  *)[data bytes];`
328.  `size_t srclen =  (size_t)data.length;`
329.  `size_t block_size =  SecKeyGetBlockSize(keyRef)  *  sizeof(uint8_t);`
330.  `void  *outbuf = malloc(block_size);`
331.  `size_t src_block_size = block_size -  11;`
332.  `NSMutableData  *ret =  [[NSMutableData alloc] init];`
333.  `for  (int idx =  0; idx < srclen; idx += src_block_size)`
334.  `{`
335.  `size_t data_len = srclen - idx;`
336.  `if(data_len > src_block_size){`
337.  `data_len = src_block_size;`
338.  `}`
339.  `size_t outlen = block_size;`
340.  `OSStatus status = noErr;`
341.  `status =  SecKeyEncrypt(keyRef, kSecPaddingPKCS1,`
342.  `srcbuf + idx, data_len,`
343.  `outbuf,  &outlen);`
344.  `if  (status !=  0)`
345.  `{`
346.  `NSLog(@"SecKeyEncrypt fail. Error Code: %d",  (int)status);`
347.  `ret =  nil;`
348.  `break;`
349.  `}`
350.  `else`
351.  `{`
352.  `[ret appendBytes:outbuf length:outlen];`
353.  `}`
354.  `}`
355.  `free(outbuf);`
356.  `CFRelease(keyRef);`
357.  `return ret;`
358.  `}`
359.  `+  (NSData  *)decryptData:(NSData  *)data withKeyRef:(SecKeyRef)keyRef`
360.  `{`
361.  `const  uint8_t  *srcbuf =  (const  uint8_t  *)[data bytes];`
362.  `size_t srclen =  (size_t)data.length;`
363.  `size_t block_size =  SecKeyGetBlockSize(keyRef)  *  sizeof(uint8_t);`
364.  `UInt8  *outbuf = malloc(block_size);`
365.  `size_t src_block_size = block_size;`
366.  `NSMutableData  *ret =  [[NSMutableData alloc] init];`
367.  `for  (int idx =  0; idx < srclen; idx += src_block_size)`
368.  `{`
369.  `size_t data_len = srclen - idx;`
370.  `if(data_len > src_block_size)`
371.  `{`
372.  `data_len = src_block_size;`
373.  `}`
374.  `size_t outlen = block_size;`
375.  `OSStatus status = noErr;`
376.  `status =  SecKeyDecrypt(keyRef, kSecPaddingNone,`
377.  `srcbuf + idx, data_len,`
378.  `outbuf,  &outlen);`
379.  `if  (status !=  0)`
380.  `{`
381.  `NSLog(@"SecKeyEncrypt fail. Error Code: %d",  (int)status);`
382.  `ret =  nil;`
383.  `break;`
384.  `}`
385.  `else`
386.  `{`
387.  `int idxFirstZero =  -1;`
388.  `int idxNextZero =  (int)outlen;`
389.  `for  (int i =  0; i < outlen; i ++)`
390.  `{`
391.  `if  (outbuf[i]  ==  0)`
392.  `{`
393.  `if  (idxFirstZero <  0)`
394.  `{`
395.  `idxFirstZero = i;`
396.  `}`
397.  `else`
398.  `{`
399.  `idxNextZero = i;`
400.  `break;`
401.  `}`
402.  `}`
403.  `}`
404.  `NSUInteger length = idxNextZero-idxFirstZero-1;`
405.  `[ret appendBytes:&outbuf[idxFirstZero+1] length:length];`
406.  `}`
407.  `}`
408.  `free(outbuf);`
409.  `CFRelease(keyRef);`
410.  `return ret;`
411.  `}`
412.  `pragma mark - RSA Key  File  Encrypt/Decrypt  Public  Method`
413.  `+  (NSString  *)encryptString:(NSString  *)originString publicKeyPath:(NSString  *)publicKeyPath`
414.  `{`
415.  `//判断originString参数是否正确`
416.  `if  ((originString ==  nil)  ||  (originString == NULL))  {`
417.  `return  nil;`
418.  `}  else  if  (![originString isKindOfClass:[NSString  class]])  {`
419.  `return  nil;`
420.  `}  else  if  ([originString length]  <=  0)  {`
421.  `return  nil;`
422.  `}`
423.  `//判断publicKeyPath参数是否正确`
424.  `if  ((publicKeyPath ==  nil)  ||  (publicKeyPath == NULL))  {`
425.  `return  nil;`
426.  `}  else  if  (![publicKeyPath isKindOfClass:[NSString  class]])  {`
427.  `return  nil;`
428.  `}  else  if  ([publicKeyPath length]  <=  0)  {`
429.  `return  nil;`
430.  `}`
431.  `//获取公钥对象和需要加密的字符串内容编码数据流`
432.  `SecKeyRef publicKeyRef =  [self getPublicKeyRefWithFilePath:publicKeyPath];`
433.  `NSData  *originData =  [originString dataUsingEncoding:NSUTF8StringEncoding];`
434.  `if  ([[self  class] isEmptyKeyRef:(__bridge id)(publicKeyRef)])  {`
435.  `return  nil;`
436.  `}`
437.  `if  ((originData ==  nil)  ||  (originData == NULL))  {`
438.  `return  nil;`
439.  `}  else  if  (![originData isKindOfClass:[NSData  class]])  {`
440.  `return  nil;`
441.  `}  else  if  ([originData length]  <=  0)  {`
442.  `return  nil;`
443.  `}`
444.  `//加密源字符串内容编码数据流的数据`
445.  `NSData  *resultData =  nil;`
446.  `resultData =  [self encryptData:originData withKeyRef:publicKeyRef];`
447.  `return  [[self  class] base64EncodedStringWithData:resultData];`
448.  `}`
449.  `+  (NSString  *)decryptString:(NSString  *)encryptString privateKeyPath:(NSString  *)privateKeyPath privateKeyPwd:(NSString  *)privateKeyPwd`
450.  `{`
451.  `//判断encryptString参数是否正确`
452.  `if  ((encryptString ==  nil)  ||  (encryptString == NULL))  {`
453.  `return  nil;`
454.  `}  else  if  (![encryptString isKindOfClass:[NSString  class]])  {`
455.  `return  nil;`
456.  `}  else  if  ([encryptString length]  <=  0)  {`
457.  `return  nil;`
458.  `}`
459.  `//判断publicKeyPath参数是否正确`
460.  `if  ((privateKeyPath ==  nil)  ||  (privateKeyPath == NULL))  {`
461.  `return  nil;`
462.  `}  else  if  (![privateKeyPath isKindOfClass:[NSString  class]])  {`
463.  `return  nil;`
464.  `}  else  if  ([privateKeyPath length]  <=  0)  {`
465.  `return  nil;`
466.  `}`
467.  `//判断密码是否存在`
468.  `NSString  *keyPassword =  [NSString stringWithFormat:@"%@",privateKeyPwd];`
469.  `if  ((privateKeyPwd ==  nil)  ||  (privateKeyPwd == NULL))  {`
470.  `keyPassword =  @"";`
471.  `}  else  if  (![privateKeyPwd isKindOfClass:[NSString  class]])  {`
472.  `keyPassword =  @"";`
473.  `}  else  if  ([privateKeyPwd length]  <=  0)  {`
474.  `keyPassword =  @"";`
475.  `}`
476.  `//获取私钥对象和需要加密的字符串内容编码数据流`
477.  `NSData  *encryptData =  nil,  *decryptData =  nil;`
478.  `SecKeyRef privateKeyRef =  [self getPrivateKeyRefWithFilePath:privateKeyPath`
479.  `keyPassword:privateKeyPwd];`
480.  `encryptData =  [[self  class] base64DecodeDataWithString:encryptString];`
481.  `if  ([[self  class] isEmptyKeyRef:(__bridge id)(privateKeyRef)])  {`
482.  `return  nil;`
483.  `}`
484.  `if  ((encryptData ==  nil)  ||  (encryptData == NULL))  {`
485.  `return  nil;`
486.  `}  else  if  (![encryptData isKindOfClass:[NSData  class]])  {`
487.  `return  nil;`
488.  `}  else  if  ([encryptData length]  <=  0)  {`
489.  `return  nil;`
490.  `}`
491.  `NSStringEncoding encoding = NSUTF8StringEncoding;`
492.  `decryptData =  [self decryptData:encryptData withKeyRef:privateKeyRef];`
493.  `return  [[NSString alloc] initWithData:decryptData encoding:encoding];`
494.  `}`
495.  `pragma mark - RSA Key  String  Encrypt/Decrypt  Public  Method`
496.  `+  (NSData  *)encryptData:(NSData  *)originData publicKey:(NSString  *)publicKey`
497.  `{`
498.  `//判断originData参数是否正确`
499.  `if  ((originData ==  nil)  ||  (originData == NULL))  {`
500.  `return  nil;`
501.  `}  else  if  (![originData isKindOfClass:[NSData  class]])  {`
502.  `return  nil;`
503.  `}  else  if  ([originData length]  <=  0)  {`
504.  `return  nil;`
505.  `}`
506.  `//判断publicKeyPath参数是否正确`
507.  `if  ((publicKey ==  nil)  ||  (publicKey == NULL))  {`
508.  `return  nil;`
509.  `}  else  if  (![publicKey isKindOfClass:[NSString  class]])  {`
510.  `return  nil;`
511.  `}  else  if  ([publicKey length]  <=  0)  {`
512.  `return  nil;`
513.  `}`
514.  `//获取需要加密的字符串内容编码数据流`
515.  `SecKeyRef publicKeyRef =  [self publicKeyRefWithPublicKey:publicKey];`
516.  `if([[self  class] isEmptyKeyRef:(__bridge id)(publicKeyRef)]){`
517.  `return  nil;`
518.  `}`
519.  `return  [self encryptData:originData withKeyRef:publicKeyRef];`
520.  `}`
521.  `+  (NSString  *)encryptString:(NSString  *)originString publicKey:(NSString  *)publicKey`
522.  `{`
523.  `//判断publicKey参数是否正确`
524.  `if  ((publicKey ==  nil)  ||  (publicKey == NULL))  {`
525.  `return  nil;`
526.  `}  else  if  (![publicKey isKindOfClass:[NSString  class]])  {`
527.  `return  nil;`
528.  `}  else  if  ([publicKey length]  <=  0)  {`
529.  `return  nil;`
530.  `}`
531.  `//判断originString参数是否正确`
532.  `if  ((originString ==  nil)  ||  (originString == NULL))  {`
533.  `return  nil;`
534.  `}  else  if  (![originString isKindOfClass:[NSString  class]])  {`
535.  `return  nil;`
536.  `}  else  if  ([originString length]  <=  0)  {`
537.  `return  nil;`
538.  `}`
539.  `//获取需要加密的字符串内容编码数据流`
540.  `NSData  *originData =  nil,  *encryptData =  nil;`
541.  `SecKeyRef publicKeyRef =  [self publicKeyRefWithPublicKey:publicKey];`
542.  `originData =  [originString dataUsingEncoding:NSUTF8StringEncoding];`
543.  `if([[self  class] isEmptyKeyRef:(__bridge id)(publicKeyRef)]){`
544.  `return  nil;`
545.  `}`
546.  `if  ((originData ==  nil)  ||  (originData == NULL))  {`
547.  `return  nil;`
548.  `}  else  if  (![originData isKindOfClass:[NSData  class]])  {`
549.  `return  nil;`
550.  `}  else  if  ([originData length]  <=  0)  {`
551.  `return  nil;`
552.  `}`
553.  `encryptData =  [self encryptData:originData withKeyRef:publicKeyRef];`
554.  `return  [[self  class] base64EncodedStringWithData:encryptData];`
555.  `}`
556.  `+  (NSString  *)decryptString:(NSString  *)encryptString privateKey:(NSString  *)privateKey`
557.  `{`
558.  `//判断publicKey参数是否正确`
559.  `if  ((privateKey ==  nil)  ||  (privateKey == NULL))  {`
560.  `return  nil;`
561.  `}  else  if  (![privateKey isKindOfClass:[NSString  class]])  {`
562.  `return  nil;`
563.  `}  else  if  ([privateKey length]  <=  0)  {`
564.  `return  nil;`
565.  `}`
566.  `//判断originString参数是否正确`
567.  `if  ((encryptString ==  nil)  ||  (encryptString == NULL))  {`
568.  `return  nil;`
569.  `}  else  if  (![encryptString isKindOfClass:[NSString  class]])  {`
570.  `return  nil;`
571.  `}  else  if  ([encryptString length]  <=  0)  {`
572.  `return  nil;`
573.  `}`
574.  `//获取私钥对象和需要加密的字符串内容编码数据流`
575.  `SecKeyRef privateKeyRef;`
576.  `NSData  *encryptData =  nil,  *decryptData =  nil;`
577.  `privateKeyRef =  [[self  class] privateKeyRefWithPrivateKey:privateKey];`
578.  `encryptData =  [[self  class] base64DecodeDataWithString:encryptString];`
579.  `if  ([[self  class] isEmptyKeyRef:(__bridge id)(privateKeyRef)])  {`
580.  `return  nil;`
581.  `}`
582.  `if  ((encryptData ==  nil)  ||  (encryptData == NULL))  {`
583.  `return  nil;`
584.  `}  else  if  (![encryptData isKindOfClass:[NSData  class]])  {`
585.  `return  nil;`
586.  `}  else  if  ([encryptData length]  <=  0)  {`
587.  `return  nil;`
588.  `}`
589.  `NSStringEncoding encoding = NSUTF8StringEncoding;`
590.  `decryptData =  [self decryptData:encryptData withKeyRef:privateKeyRef];`
591.  `return  [[NSString alloc] initWithData:decryptData encoding:encoding];`
592.  `}`
593.  `/******************************************************************************/`

在iOS中RSA加解密使用方法介绍(RSA密钥格式请使用PKCS#8格式)


1.  `//使用RSA执行加密操作`
2.  `NSString  *string4 =  @"abcdefghijklmnopqrstuvwxyz";`
3.  `NSString  *encodeString4 =  [RSAEncrypt encryptString:string4`
4.  `publicKey:mPublicKey];`
5.  `NSLog(@"encodeString4 : %@", encodeString4);`
6.  `//使用RSA执行解密操作`
7.  `NSString  *decodeString4 =  [RSAEncrypt decryptString:encodeString4`
8.  `privateKey:mPrivateKey];`
9.  `NSLog(@"decodeString4 : %@", decodeString4);`

github 地址:https://github.com/wenjing0628/encryptDemo

上一篇下一篇

猜你喜欢

热点阅读