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