iPhone开发之AES加密和解密
参考来自:http://zhiwei.li/text/2011/07/iphone%E4%B8%8Aaes%E5%8A%A0%E5%AF%86%E7%9A%84%E5%AE%9E%E7%8E%B0/
头文件 NSDataEncryption.h
#import <UIKit/UIKit.h> @interface NSData (AES256) - (NSData *)AES256EncryptWithKey:(NSString *)key;//加密 - (NSData *)AES256DecryptWithKey:(NSString *)key;//解密 @end
实现 NSDataEncryption.m
#import "NSDataEncryption.h" #import <CommonCrypto/CommonDigest.h> #import <CommonCrypto/CommonCryptor.h> #import <CommonCrypto/CommonHMAC.h> @implementation NSData (AES256) - (NSData *)AES256EncryptWithKey:(NSString *)key { // 'key' should be 32 bytes for AES256, will be null-padded otherwise char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused) bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding) // fetch key data [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; NSUInteger dataLength = [self length]; //See the doc: For block ciphers, the output size will always be less than or //equal to the input size plus the size of one block. //That's why we need to add the size of one block here size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesEncrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, keyPtr, kCCKeySizeAES256, NULL /* initialization vector (optional) */, [self bytes], dataLength, /* input */ buffer, bufferSize, /* output */ &numBytesEncrypted); if (cryptStatus == kCCSuccess) { //the returned NSData takes ownership of the buffer and will free it on deallocation return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; } free(buffer); //free the buffer; return nil; } - (NSData *)AES256DecryptWithKey:(NSString *)key { // 'key' should be 32 bytes for AES256, will be null-padded otherwise char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused) bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding) // fetch key data [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; NSUInteger dataLength = [self length]; //See the doc: For block ciphers, the output size will always be less than or //equal to the input size plus the size of one block. //That's why we need to add the size of one block here size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesDecrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, keyPtr, kCCKeySizeAES256, NULL /* initialization vector (optional) */, [self bytes], dataLength, /* input */ buffer, bufferSize, /* output */ &numBytesDecrypted); if (cryptStatus == kCCSuccess) { //the returned NSData takes ownership of the buffer and will free it on deallocation return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted]; } free(buffer); //free the buffer; return nil; } @end
使用方法:
NSString *key = @"my password";//密码 NSString *secret = @"text to encrypt";//要加密的文本 //加密过程 NSData *plain = [secret dataUsingEncoding:NSUTF8StringEncoding]; //NSString转为NSData NSData *cipher = [plain AES256EncryptWithKey:key];//ASE加密后的密码 printf("%s\n", [[cipher description] UTF8String]);//输出secret通过key后的AES加密内容 //解密过程 plain = [cipher AES256DecryptWithKey:key];//对cipher进行解密 printf("%s\n", [[plain description] UTF8String]); printf("%s\n", [[[NSString alloc] initWithData:plain encoding:NSUTF8StringEncoding] UTF8String]);
开源项目参考:https://github.com/AlanQuatermain/aqtoolkit/tree/master/CommonCrypto/