10一/111
iPhone开发技巧之数据篇(2)— iPhone程序中的加密处理
iPhone开发技巧之数据篇(2)— iPhone程序中的加密处理
CCCrypt
在Objective-C语言中,加密时常用到CCCrypt(3cc) Mac OS X Manual Page。下面的代码使用 CCCrypt() ,给 NSData 类增加了 AES256EncryptWithKey, AES256DecryptWithKey 方法。
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 |
#import <CommonCrypto/CommonCryptor.h> @implementation NSData (Additions) @class NSString; - (NSData *)AES256EncryptWithKey:(NSString *)key { char keyPtr[kCCKeySizeAES256+1]; bzero(keyPtr, sizeof(keyPtr)); [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; NSUInteger dataLength = [self length]; size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesEncrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding | kCCOptionECBMode, keyPtr, kCCBlockSizeAES128, NULL, [self bytes], dataLength, buffer, bufferSize, &numBytesEncrypted); if (cryptStatus == kCCSuccess) { return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; } free(buffer); return nil; } - (NSData *)AES256DecryptWithKey:(NSString *)key { char keyPtr[kCCKeySizeAES256+1]; bzero(keyPtr, sizeof(keyPtr)); [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; NSUInteger dataLength = [self length]; size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesDecrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding | kCCOptionECBMode, keyPtr, kCCBlockSizeAES128, NULL, [self bytes], dataLength, buffer, bufferSize, &numBytesDecrypted); if (cryptStatus == kCCSuccess) { return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted]; } free(buffer); return nil; } @end |
使用的时候就像使用NSData一样。
base64encoding
有的时候需要向服务器上传递base64加密的数据,这个时候我们就可以像下面,给 NSData 类追加newStringInBase64FromData 方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
- (NSString *)newStringInBase64FromData { NSMutableString *dest = [[NSMutableString alloc] initWithString:@""]; unsigned char * working = (unsigned char *)[self bytes]; int srcLen = [self length]; for (int i=0; i<srcLen; i += 3) { for (int nib=0; nib<4; nib++) { int byt = (nib == 0)?0:nib-1; int ix = (nib+1)*2; if (i+byt >= srcLen) break; unsigned char curr = ((working[i+byt] << (8-ix)) & 0x3F); if (i+nib < srcLen) curr |= ((working[i+nib] >> ix) & 0x3F); [dest appendFormat:@"%c", base64[curr]]; } } return dest; } |
同样,使用的时候就像使用NSData一样。
最终的代码如下所示 :
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 |
// // NSDataAdditions.h // // Copyright 2010 __MyCompanyName__. All rights reserved. // #import <Foundation/Foundation.h> @class NSString; @interface NSData (Additions) - (NSData *)AES256EncryptWithKey:(NSString *)key; - (NSData *)AES256DecryptWithKey:(NSString *)key; - (NSString *)newStringInBase64FromData; @end // ----------------------------------------------------------------------------------- // // NSDataAdditions.m // // Copyright 2010 __MyCompanyName__. All rights reserved. // #import "NSDataAdditions.h" #import <CommonCrypto/CommonCryptor.h> static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @implementation NSData (Additions) @class NSString; - (NSData *)AES256EncryptWithKey:(NSString *)key { char keyPtr[kCCKeySizeAES256+1]; bzero(keyPtr, sizeof(keyPtr)); [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; NSUInteger dataLength = [self length]; size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesEncrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding | kCCOptionECBMode, keyPtr, kCCBlockSizeAES128, NULL, [self bytes], dataLength, buffer, bufferSize, &numBytesEncrypted); if (cryptStatus == kCCSuccess) { return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; } free(buffer); return nil; } - (NSData *)AES256DecryptWithKey:(NSString *)key { char keyPtr[kCCKeySizeAES256+1]; bzero(keyPtr, sizeof(keyPtr)); [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; NSUInteger dataLength = [self length]; size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesDecrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding | kCCOptionECBMode, keyPtr, kCCBlockSizeAES128, NULL, [self bytes], dataLength, buffer, bufferSize, &numBytesDecrypted); if (cryptStatus == kCCSuccess) { return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted]; } free(buffer); return nil; } - (NSString *)newStringInBase64FromData { NSMutableString *dest = [[NSMutableString alloc] initWithString:@""]; unsigned char * working = (unsigned char *)[self bytes]; int srcLen = [self length]; for (int i=0; i<srcLen; i += 3) { for (int nib=0; nib<4; nib++) { int byt = (nib == 0)?0:nib-1; int ix = (nib+1)*2; if (i+byt >= srcLen) break; unsigned char curr = ((working[i+byt] << (8-ix)) & 0x3F); if (i+nib < srcLen) curr |= ((working[i+nib] >> ix) & 0x3F); [dest appendFormat:@"%c", base64[curr]]; } } return dest; } @end |
相关文章
- iPhone开发技巧之发布篇(7)--- 制作自己的Cydia发布源 - (2012-01-20)
- iPhone开发技巧之发布篇(6)--- 不需Developper认证的真机调试方法 - (2011-12-25)
- iPhone开发技巧之环境篇(11) --- 让Xcode对应多个版本的iOS SDK - (2011-12-03)
- iPhone开发技巧之发布篇(5)--- 在程序中添加广告 - (2011-11-20)
- iPhone开发技巧之环境篇(10)--- 在控制台调试iPhone应用程序 - (2011-11-13)
- iPhone开发技巧之调试篇(3)--- 程序Crash后的调试技巧 - (2011-11-06)
- iPhone开发技巧之环境篇(9)--- Xcode中的注释 - (2011-01-12)
- iPhone开发技巧之发布篇(4)--- 使用 Ad Hoc 发布自己的应用程序 - (2010-07-22)
- iPhone开发技巧之发布篇(3)--- 你的程序被拒了吗? - (2010-07-19)
- iPhone开发技巧之发布篇(2)--- 税务相关手续 - (2010-07-16)
- iPhone开发技巧之发布篇(1)--- 登录银行信息 - (2010-07-12)
- iPhone开发技巧之工具篇(4)--- 使用afconvert转换WAV文件 - (2010-06-24)
- iPhone开发技巧之私有API(8)--- UIApplication - (2010-06-18)
- iPhone开发技巧之私有API(7)--- 用UIWebView访问BASIC认证的页面 - (2010-06-16)
- iPhone开发技巧之私有API(6)--- 设置UIWebView中的User-Agent - (2010-06-14)
- iPhone开发技巧之私有API(5)--- UISegmentedControl - (2010-06-11)
- iPhone开发技巧之私有API(4)--- UIBarButtonItem - (2010-06-09)
- iPhone开发技巧之私有API(3)--- UIButton - (2010-06-07)
- iPhone开发技巧之数据篇(1)--- 使用正则表达式 - (2010-06-04)
- iPhone开发技巧之私有API(2)--- UITableView - (2010-06-01)
- iPhone开发技巧之私有API(1) --- 设备相关信息 - (2010-05-28)
- iPhone开发技巧之网络篇(5)--- 使用libcurl连接https服务器 - (2010-05-17)
- iPhone开发技巧之网络篇(4)--- 确认网络环境 3G/WIFI - (2010-05-14)
- iPhone开发技巧之网络篇(3)--- 使用NSOperation建立多任务网络连接 - (2010-05-12)
- iPhone开发技巧之网络篇(2)--- Web服务 - (2010-04-20)
2011年01月26日 18:16
相当好的文章,值得学习。
不过函数中存在内存泄漏的问题,还得微调修正一下吧?例如AES256DecryptWithKey中的dest,是否autorelease会好一些?请指正。