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