AES是开发中常用的加密算法之一,在多平台统一加密时,需要统一的几个参数:
• 密钥长度(Key Size)
本文中使用的是AES-128,已能够满足商用安全需求。
• 加密模式(Cipher Mode)
有CBC、ECB、CTR、OFB、CFB等几种,本文使用CBC模式。
• 填充方式(Padding)
iOS SDK中提供了PKCS7Padding,与JDK中的PKCS5Padding是相等的。
• 初始向量(Initialization Vector)
除ECB以外的其他加密模式均需要传入一个初始向量,其大小与Block Size相等。其他加密模式当不传入初始向量时,系统将默认使用一个全0的初始向量。
具体实现
.h文件如下:
#import <Foundation/Foundation.h>NSString * aesEncryptString(NSString *content, NSString *key, NSString *iv);NSString * aesDecryptString(NSString *content, NSString *key, NSString *iv);NSData * aesEncryptData(NSData *contentData, NSData *keyData, NSData *ivData);NSData * aesDecryptData(NSData *contentData, NSData *keyData, NSData *ivData);
.m文件如下:
#import <CommonCrypto/CommonCryptor.h>NSData * cipherOperation(NSData *contentData, NSData *keyData, NSData *ivData, CCOperation operation) { NSUInteger dataLength = contentData.length; void const *initVectorBytes = ivData.bytes; void const *contentBytes = contentData.bytes; void const *keyBytes = keyData.bytes; size_t operationSize = dataLength + kCCBlockSizeAES128; void *operationBytes = malloc(operationSize); if (operationBytes == NULL) { return nil; } size_t actualOutSize = 0; CCCryptorStatus cryptStatus = CCCrypt(operation, kCCAlgorithmAES, kCCOptionPKCS7Padding, // 与其他平台的PKCS5Padding相等 keyBytes, kCCKeySizeAES128, // 秘钥长度选择AES128 initVectorBytes, contentBytes, dataLength, operationBytes, operationSize, &actualOutSize); if (cryptStatus == kCCSuccess) { return [NSData dataWithBytesNoCopy:operationBytes length:actualOutSize]; } free(operationBytes); operationBytes = NULL; return nil;}NSString * aesEncryptString(NSString *content, NSString *key, NSString *iv) { NSData *contentData = [content dataUsingEncoding:NSUTF8StringEncoding]; NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding]; NSData *ivData = [iv dataUsingEncoding:NSUTF8StringEncoding]; NSData *encrptedData = aesEncryptData(contentData, keyData, ivData); return [encrptedData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];}NSString * aesDecryptString(NSString *content, NSString *key, NSString *iv) { NSData *contentData = [[NSData alloc] initWithBase64EncodedString:content options:NSDataBase64DecodingIgnoreUnknownCharacters]; NSData *keyData = [key dataUsingEncoding:NSUTF8StringEncoding]; NSData *ivData = [iv dataUsingEncoding:NSUTF8StringEncoding]; NSData *decryptedData = aesDecryptData(contentData, keyData, ivData); return [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];}NSData * aesEncryptData(NSData *contentData, NSData *keyData, NSData *ivData) { return cipherOperation(contentData, keyData, ivData, kCCEncrypt);}NSData * aesDecryptData(NSData *contentData, NSData *keyData, NSData *ivData) { return cipherOperation(contentData, keyData, ivData, kCCDecrypt);}
注意
以上实现的是AES-128,因此方法传入的秘钥key和向量iv需要长度为16的字符串。