iOS AES加密

AES 美国国家安全局采用的加密方法,MAC 系统自带的钥匙串也是采用的AES 加密方法

有两种模式

CBC 模式 链式加密 ,密码块链,使用一个秘钥和一个初始化向量,对数据执行加密。

ECB 电子密码本方法加密,数据拆分成块,独立加密。

mac 系统已经集成openssl 工具,可以直接文本进行加密

1 打开终端 桌面新建一个文件夹,cd 到里面,touch一个abc.txt

2 openssl enc -des-ecb -K 616263 -nosalt -in abc.txt -out msg1.bin

enc 代表加密

-des-ecb 代表ecb 模式

-k 代表 key 值

-nosalt 代表不加盐

-in abc.txt 代表 读取里面内容

-out msg1.bin 代表输出为msg1.bin 二进制文件

3 xxd 查看二进制文件

xxd msg1.bin

AES是开发中常用的加密算法之一。然而由于前后端开发使用的语言不统一,导致经常出现前端加密而后端不能解密的情况出现。然而无论什么语言系统,AES的算法总是相同的, 因此导致结果不一致的原因在于 加密设置的参数不一致 。于是先来看看在两个平台使用AES加密时需要统一的几个参数。

密钥长度(Key Size)
加密模式(Cipher Mode)
填充方式(Padding)
初始向量(Initialization Vector)

密钥长度

AES算法下,key的长度有三种:128、192和256 bits。由于历史原因,JDK默认只支持不大于128 bits的密钥,而128 bits的key已能够满足商用安全需求。因此本例先使用AES-128。(Java使用大于128 bits的key方法在文末提及)

加密模式

AES属于块加密(Block Cipher),块加密中有CBC、ECB、CTR、OFB、CFB等几种工作模式。本例统一使用CBC模式。

填充方式

由于块加密只能对特定长度的数据块进行加密,因此CBC、ECB模式需要在最后一数据块加密前进行数据填充。(CFB,OFB和CTR模式由于与key进行加密操作的是上一块加密后的密文,因此不需要对最后一段明文进行填充)

在iOS SDK中提供了PKCS7Padding,而JDK则提供了PKCS5Padding。原则上PKCS5Padding限制了填充的Block Size为8 bytes,而Java实际上当块大于该值时,其PKCS5Padding与PKCS7Padding是相等的:每需要填充χ个字节,填充的值就是χ。

初始向量

使用除ECB以外的其他加密模式均需要传入一个初始向量,其大小与Block Size相等(AES的Block Size为128 bits),而两个平台的API文档均指明当不传入初始向量时,系统将默认使用一个全0的初始向量。

引入NSString+Encryption.h" 文件

CocoaSecurity 框架基本实现了所有的加密方式

#import "ViewController.h"


#import "NSString+Encryption.h"
#import "CocoaSecurity.h"




@interface ViewController ()


@end


@implementation ViewController


- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self aesecbMode];
    
}


    
    


/**
 AES CBC 模式加密的使用
 
 CocoaSecurity 是一个用于加解密的框架,封装了各种加密方法的使用,用此框架来校验NSString+Encryption.h 加解密结果是否一样
 CocoaSecurity 框架,解密的时候传入的参数都是16进制
 */
    
    
- (void)aescbcMode{
    
    NSString *plainText = @"你好";
// key 16字节的字符串,就等于128 bite
// key支持 128 192 256 bite,分别对象 16 24 32 长度单位
// 如果长度错误,就会跑出异常
    NSString *key128 = @"0123456789ABCDEF";
    // 16进制字符串
    NSString *key128Hex = @"30313233343536373839414243444546";
    
    NSString *iv = @"0123456789ABCDEF";
    // 16进制字符串
    NSString *ivHex = @"30313233343536373839414243444546";
    
    CocoaSecurityResult *result = [CocoaSecurity aesEncrypt:plainText hexKey:key128Hex hexIv:ivHex];
    
    NSString *aesBase64 = [plainText aesEncryptWithKey:key128 iv:iv];
    NSData *aesData = [plainText aesEncryptWithDataKey:[key128 dataUsingEncoding:NSUTF8StringEncoding] dataIv:[iv dataUsingEncoding:NSUTF8StringEncoding]];
    NSLog(@"SecurityResult加密:\r\n%@ --- %@",result.base64,result.hexLower);
    NSLog(@"NSString+Encryption加密:\r\n%@ --- %@",aesBase64,aesData);
    
    
    // 解密
    NSString *decryptStr = [aesBase64 aesBase64StringDecryptWithHexKey:key128Hex hexIv:ivHex];
    NSData *data = [NSString aesDecryptWithData:aesData dataKey:[key128 dataUsingEncoding:NSUTF8StringEncoding] dataIv:[iv dataUsingEncoding:NSUTF8StringEncoding]];
   
    // 使用CocoaSecurity 和 封装的方法 加解密结果进行校验
    NSLog(@"解密:%@ --- %@",decryptStr, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);


}
    
/**
    AES EBC 模式加解密,EBC 模式
 
 */


- (void)aesecbMode{
    NSString *plainText = @"123";
    
    NSString *key128 = @"0123456789ABCDEF";
    // key 16进制形式
    NSString *key128Hex = @"30313233343536373839414243444546";
    
    NSString *aesBase64 = [plainText aesECBEncryptWithKey:key128];
    NSData *aesData = [plainText aesECBEncryptWithDataKey:[key128 dataUsingEncoding:NSUTF8StringEncoding]];
    NSLog(@"加密:%@ --- %@",aesBase64, aesData);
    
    // 解密
    NSString *decStr = [aesBase64 aesECBBase64StringDecryptWithHexKey:key128Hex];
    NSData *decData = [NSString aesECBDecryptWithData:aesData withDataKey:[key128 dataUsingEncoding:NSUTF8StringEncoding]];
    NSLog(@"解密:%@---%@",decStr, [[NSString alloc]initWithData:decData encoding:NSUTF8StringEncoding]);


}


    /**
     AEC  框架是<CommonCrypto/CommonCrypto.h>
     加解密所用的同一个核心方法
     
     @param option 加密还是解密 枚举类型 kCCEncrypt 加密  kCCDecrypt 解密
     @param kCCAlgorithmAES128 加密算法 默认是AES
     @param mode kCCOptionPKCS7Padding 为CBC 加密 默认是CBC 加密
     kCCOptionPKCS7Padding  | kCCOptionECBMode 为ECB 加密
     @param bytes] 加密秘钥
     @param length] 秘钥长度
     @param bytes] IV 初始化向量
     @param bytes] 加密的数据
     @param length] 数据的长度
     @param buffer 密文缓冲区
     @param bufferSize 缓冲区的大小
     @param encryptedSize
     @return 加密的结果
     */
//    CCCryptorStatus cryptStatus = CCCrypt(option,
//                                          kCCAlgorithmAES128,
//                                          mode,
//                                          [key bytes],     // Key
//                                          [key length],    // kCCKeySizeAES
//                                          [iv bytes],      // IV
//                                          [data bytes],
//                                          [data length],
//                                          buffer,
//                                          bufferSize,
//                                          &encryptedSize);


    


@end
iOS中使用AES加密可以使用CommonCrypto库提供的API实现。具体步骤如下: 1. 引入头文件: ```objective-c #import <CommonCrypto/CommonCryptor.h> ``` 2. 定义加密/解密方法: ```objective-c // 加密方法 + (NSString *)encrypt:(NSString *)content key:(NSString *)key iv:(NSString *)iv { char keyPtr[kCCKeySizeAES256 + 1]; memset(keyPtr, 0, sizeof(keyPtr)); [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; char ivPtr[kCCBlockSizeAES128 + 1]; memset(ivPtr, 0, sizeof(ivPtr)); [iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding]; NSData *data = [content dataUsingEncoding:NSUTF8StringEncoding]; NSUInteger dataLength = [data length]; int bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesEncrypted = 0; CCCryptorStatus status = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding | kCCOptionECBMode, keyPtr, kCCBlockSizeAES128, ivPtr, [data bytes], dataLength, buffer, bufferSize, &numBytesEncrypted); if (status == kCCSuccess) { NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; return [resultData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed]; } free(buffer); return nil; } // 解密方法 + (NSString *)decrypt:(NSString *)content key:(NSString *)key iv:(NSString *)iv { char keyPtr[kCCKeySizeAES256 + 1]; memset(keyPtr, 0, sizeof(keyPtr)); [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; char ivPtr[kCCBlockSizeAES128 + 1]; memset(ivPtr, 0, sizeof(ivPtr)); [iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding]; NSData *data = [[NSData alloc] initWithBase64EncodedString:content options:NSDataBase64DecodingIgnoreUnknownCharacters]; NSUInteger dataLength = [data length]; int bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesDecrypted = 0; CCCryptorStatus status = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding | kCCOptionECBMode, keyPtr, kCCBlockSizeAES128, ivPtr, [data bytes], dataLength, buffer, bufferSize, &numBytesDecrypted); if (status == kCCSuccess) { NSData *resultData = [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted]; return [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding]; } free(buffer); return nil; } ``` 3. 调用加密/解密方法: ```objective-c NSString *key = @"1234567890123456"; NSString *iv = @"1234567890123456"; NSString *content = @"hello, world"; NSString *encryptedContent = [self encrypt:content key:key iv:iv]; NSLog(@"加密后:%@", encryptedContent); NSString *decryptedContent = [self decrypt:encryptedContent key:key iv:iv]; NSLog(@"解密后:%@", decryptedContent); ``` 需要注意的是,在ECB模式下,iv的值不会被使用,但是仍然需要传入一个长度为16的字符串。另外,加密后的结果需要使用base64编码才能转换为字符串,解密前需要先对密文进行base64解码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值