AES CBC加密/解密
阿新 • • 發佈:2019-01-11
簡介
高階加密標準(英語:Advanced Encryption Standard,縮寫:AES),在密碼學中又稱Rijndael加密法,是美國聯邦政府採用的一種區塊加密標準。這個標準用來替代原先的DES,已經被多方分析且廣為全世界所使用。經過五年的甄選流程,高階加密標準由美國國家標準與技術研究院(NIST)於2001年11月26日釋出於FIPS PUB 197,並在2002年5月26日成為有效的標準。2006年,高階加密標準已然成為對稱金鑰加密中最流行的演算法之一。
AES-128-CBC是一種分組對稱加密演算法,即用同一組key進行明文和密文的轉換,以128bit為一組,128bit==16Byte,意思就是明文的16位元組為一組對應加密後的16位元組的密文。
若最後剩餘的明文不夠16位元組,需要進行填充,通常採用PKCS7進行填充。比如最後缺3個位元組,則填充3個位元組的0x03;若最後缺10個位元組,則填充10個位元組的0x0a;
若明文正好是16個位元組的整數倍,最後要再加入一個16位元組0x10的組再進行加密
背景
最近開發數字貨幣個人交易錢包,需要對相關敏感資料加密。其中就使用AES 演算法實現相關加密、解密。
NSData+AES.h檔案如下:
// // NSData+AES.h // cmd-test // // Created by vincent on 2018/11/14. // Copyright © 2018年 vincent. All rights reserved. // #import <Foundation/Foundation.h> /** *AES 加密/解密 *AES128 加密/解密 key 必須是16位元組(128 = 16 * 8) * 如果需要AES256 加密/解密 key 必須是32位元組(256 = 32 * 8) */ typedef NS_ENUM(NSUInteger, AESLengthType) { AES128Type, AES256Type, }; @interface NSData (AES) /** *@param key 加密金鑰 *@param type AES128/AES256型別 *@param iv cbc加解密資料 **/ -(NSData *)aesEncryptWithKey:(NSData *)key type:(AESLengthType)type initVector:(NSData *)iv; -(NSData *)aesDecryptWithKey:(NSData *)key type:(AESLengthType)type initVector:(NSData *)iv; @end
NSData+AES.m檔案如下:
// // NSData+AES.m // cmd-test // // Created by vincent on 2018/11/14. // Copyright © 2018年 vincent. All rights reserved. // #import "NSData+AES.h" #import <CommonCrypto/CommonCryptor.h> @implementation NSData (AES) -(NSData *)cipherOperationWithKey:(NSData *)key keyLength:(int)len initVector:(NSData *)iv operation:(CCOperation)op{ NSUInteger dataLength = self.length; void const *initVectorBytes = iv.bytes; void const *contentBytes = self.bytes; void const *keyBytes = key.bytes; size_t kKeySize = len; size_t operationSize = dataLength + kCCBlockSizeAES128; void *operationBytes = malloc(operationSize); if (operationBytes == NULL) { return nil; } size_t actualOutSize = 0; CCCryptorStatus cryptStatus = CCCrypt(op, kCCAlgorithmAES, kCCOptionPKCS7Padding, keyBytes, kKeySize, initVectorBytes, contentBytes, dataLength, operationBytes, operationSize, &actualOutSize); if (cryptStatus == kCCSuccess) { return [NSData dataWithBytesNoCopy:operationBytes length:actualOutSize]; } free(operationBytes); operationBytes = NULL; return nil; } -(NSData *)aesEncryptWithKey:(NSData *)key type:(AESLengthType)type initVector:(NSData *)iv{ int len = type == AES128Type ? kCCKeySizeAES128 : kCCKeySizeAES256; NSString *hint = [NSString stringWithFormat:@"The key size of AES-%d should be %d bytes!", len * 8, len]; NSCAssert(key.length == len, hint); return [self cipherOperationWithKey:key keyLength:len initVector:iv operation:kCCEncrypt]; } -(NSData *)aesDecryptWithKey:(NSData *)key type:(AESLengthType)type initVector:(NSData *)iv{ int len = type == AES128Type ? kCCKeySizeAES128 : kCCKeySizeAES256; NSString *hint = [NSString stringWithFormat:@"The key size of AES-%d should be %d bytes!", len * 8, len]; NSCAssert(key.length == len, hint); return [self cipherOperationWithKey:key keyLength:len initVector:iv operation:kCCDecrypt]; } @end
我們對NSData 新增分類實現對NSData 資料的加密解密!