先直接贴上源码吧,给NSData添加加密、解密的扩展:
.h文件
#import <Foundation/Foundation.h>
@interface NSData (AES)
//加密
- (NSData *)AES128EncryptWithKey:(NSString *)key iv:(NSString *)iv;
//解密
- (NSData *)AES128DecryptWithKey:(NSString *)key iv:(NSString *)iv;
@end
.m文件
#import "NSData+AES.h"
#import <CommonCrypto/CommonCryptor.h>
@implementation NSData (AES)
//加密
- (NSData *)AES128EncryptWithKey:(NSString *)key iv:(NSString *)iv
{
return [self AES128operation:kCCEncrypt key:key iv:iv];
}
//解密
- (NSData *)AES128DecryptWithKey:(NSString *)key iv:(NSString *)iv
{
return [self AES128operation:kCCDecrypt key:key iv:iv];
}
- (NSData *)AES128operation:(CCOperation)operation key:(NSString *)key iv:(NSString *)iv
{
char keyPtr[kCCKeySizeAES128 + 1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
// IV
char ivPtr[kCCBlockSizeAES128 + 1];
bzero(ivPtr, sizeof(ivPtr));
[iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
size_t bufferSize = [self length] + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptorStatus = CCCrypt(operation, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES128,
ivPtr,
[self bytes], [self length],
buffer, bufferSize,
&numBytesEncrypted);
if(cryptorStatus == kCCSuccess){
NSLog(@"Success");
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}else{
NSLog(@"Error");
}
free(buffer);
return nil;
}
@end
使用方法
NSString *key = @"efrVN9vy6MxuHrtG";
NSString *iv = @"N3nLasdhgypjZu3r";
NSString *str1 = @"you are not that into me";
NSData *data1 = [str1 dataUsingEncoding:NSUTF8StringEncoding];
//加密
data1 = [data1 AES128EncryptWithKey:key iv:iv];
//解密
NSData *data2 = [data1 AES128DecryptWithKey:key iv:iv];
NSString *str2 = [[NSString alloc] initWithData:data2 encoding:NSUTF8StringEncoding];
NSLog(@"str2:%@", str2);
此处加密跟解密都是在前端进行,运行项目后控制台能正确的打印 “str2:you are not that into me”。但是一般采用的做法是服务器进行加密、前端进行解密。这里加密后的data1是无法转换成字符串的,所以服务器一般会采用base64进行加密生成对应的NSData,然后转成str提供给前端使用,所以前端拿到str后需要转换成NSData,然后进行base64解密,再进行AES解密才能获取正确的数据。详细代码如下:
//server处理
//server 会对AES加密后的data1 进行base64加密,然后将str提供给前端处理
NSData *data3 = [GTMBase64 encodeData:data1];
NSString *str3 = [[NSString alloc] initWithData:data3 encoding:NSUTF8StringEncoding];
NSLog(@"str3:%@", str3);
//前端处理
NSData *data4 = [str3 dataUsingEncoding:NSUTF8StringEncoding];
data4 = [GTMBase64 decodeData:data4];
NSData *data5 = [data4 AES128DecryptWithKey:key iv:iv];
NSString *str4 = [[NSString alloc] initWithData:data5 encoding:NSUTF8StringEncoding];
NSLog(@"str4:%@", str4);