美文网首页
iOS常用的加密模式

iOS常用的加密模式

作者: KingWorld | 来源:发表于2021-04-20 13:19 被阅读0次

    之前的项目中接触过一些加密的方法,也没有太仔细的进行记录和研究。最近在写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

    相关文章

      网友评论

          本文标题:iOS常用的加密模式

          本文链接:https://www.haomeiwen.com/subject/znqnlltx.html