源文件
頭文件
包含終端命令,可以驗證加密結(jié)果是否正確
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonCrypto.h>
/**
* 終端測試指令
* 其中 -k 是key的ascii碼
* 可以利用
* DES(ECB)加密
* $ echo -n hello | openssl enc -des-ecb -K 616263 -nosalt | base64
*
* DES(CBC)加密
* $ echo -n hello | openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt | base64
*
* AES(ECB)加密
* $ echo -n hello | openssl enc -aes-128-ecb -K 616263 -nosalt | base64
*
* AES(CBC)加密
* $ echo -n hello | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt | base64
*
* DES(ECB)解密
* $ echo -n HQr0Oij2kbo= | base64 -D | openssl enc -des-ecb -K 616263 -nosalt -d
*
* DES(CBC)解密
* $ echo -n alvrvb3Gz88= | base64 -D | openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt -d
*
* AES(ECB)解密
* $ echo -n d1QG4T2tivoi0Kiu3NEmZQ== | base64 -D | openssl enc -aes-128-ecb -K 616263 -nosalt -d
*
* AES(CBC)解密
* $ echo -n u3W/N816uzFpcg6pZ+kbdg== | base64 -D | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt -d
*
* 提示:
* 1> 加密過程是先加密,再base64編碼
* 2> 解密過程是先base64解碼,再解密
*/
@interface EncryptionTools : NSObject
+ (instancetype)sharedEncryptionTools;
/**
@constant kCCAlgorithmAES 高級加密標準,128位(默認)
@constant kCCAlgorithmDES 數(shù)據(jù)加密標準
*/
@property (nonatomic, assign) uint32_t algorithm;
/**
* 加密字符串并返回base64編碼字符串
*
* @param string 要加密的字符串
* @param keyString 加密密鑰
* @param iv 初始化向量(8個字節(jié))
*
* @return 返回加密后的base64編碼字符串
*/
- (NSString *)encryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv;
/**
* 解密字符串
*
* @param string 加密并base64編碼后的字符串
* @param keyString 解密密鑰
* @param iv 初始化向量(8個字節(jié))
*
* @return 返回解密后的字符串
*/
- (NSString *)decryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv;
@end
體文件
#import "EncryptionTools.h"
@interface EncryptionTools()
@property (nonatomic, assign) int keySize;
@property (nonatomic, assign) int blockSize;
@end
@implementation EncryptionTools
+ (instancetype)sharedEncryptionTools {
static EncryptionTools *instance;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[self alloc] init];
instance.algorithm = kCCAlgorithmAES;
});
return instance;
}
- (void)setAlgorithm:(uint32_t)algorithm {
_algorithm = algorithm;
switch (algorithm) {
case kCCAlgorithmAES:
self.keySize = kCCKeySizeAES128;
self.blockSize = kCCBlockSizeAES128;
break;
case kCCAlgorithmDES:
self.keySize = kCCKeySizeDES;
self.blockSize = kCCBlockSizeDES;
break;
default:
break;
}
}
- (NSString *)encryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv {
// 設(shè)置秘鑰
NSData *keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding];
uint8_t cKey[self.keySize];
bzero(cKey, sizeof(cKey));
[keyData getBytes:cKey length:self.keySize];
// 設(shè)置iv
uint8_t cIv[self.blockSize];
bzero(cIv, self.blockSize);
int option = 0;
if (iv) {
[iv getBytes:cIv length:self.blockSize];
option = kCCOptionPKCS7Padding;
} else {
option = kCCOptionPKCS7Padding | kCCOptionECBMode;
}
// 設(shè)置輸出緩沖區(qū)
NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
size_t bufferSize = [data length] + self.blockSize;
void *buffer = malloc(bufferSize);
// 開始加密
size_t encryptedSize = 0;
/*
CCCrypt:對稱加密的核心函數(shù)(加密、解密)
參數(shù):
1:加密kCCEncrypt、解密kCCDecrypt
2:加密算法 AES/DES
kCCAlgorithmAES 高級加密標準
kCCAlgorithmDES 數(shù)據(jù)加密標準
3.加密選項:ECB/CBC
4.加密的密鑰
5.密鑰長度
6.iv 初始化向量
7.加密的長度
8.加密的數(shù)據(jù)長度
9.密文的內(nèi)存地址
10.密文緩沖區(qū)大小
11.加密結(jié)果大小
*/
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
self.algorithm,
option,
cKey,
self.keySize,
cIv,
[data bytes],
[data length],
buffer,
bufferSize,
&encryptedSize);
NSData *result = nil;
if (cryptStatus == kCCSuccess) {
result = [NSData dataWithBytesNoCopy:buffer length:encryptedSize];
} else {
free(buffer);
NSLog(@"[錯誤] 加密失敗|狀態(tài)編碼: %d", cryptStatus);
}
return [result base64EncodedStringWithOptions:0];
}
- (NSString *)decryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv {
// 設(shè)置秘鑰
NSData *keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding];
uint8_t cKey[self.keySize];
bzero(cKey, sizeof(cKey));
[keyData getBytes:cKey length:self.keySize];
// 設(shè)置iv
uint8_t cIv[self.blockSize];
bzero(cIv, self.blockSize);
int option = 0;
if (iv) {
[iv getBytes:cIv length:self.blockSize];
option = kCCOptionPKCS7Padding;
} else {
option = kCCOptionPKCS7Padding | kCCOptionECBMode;
}
// 設(shè)置輸出緩沖區(qū)
NSData *data = [[NSData alloc] initWithBase64EncodedString:string options:0];
size_t bufferSize = [data length] + self.blockSize;
void *buffer = malloc(bufferSize);
// 開始解密
size_t decryptedSize = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
self.algorithm,
option,
cKey,
self.keySize,
cIv,
[data bytes],
[data length],
buffer,
bufferSize,
&decryptedSize);
NSData *result = nil;
if (cryptStatus == kCCSuccess) {
result = [NSData dataWithBytesNoCopy:buffer length:decryptedSize];
} else {
free(buffer);
NSLog(@"[錯誤] 解密失敗|狀態(tài)編碼: %d", cryptStatus);
}
return [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
}
@end
使用方法
AES - ECB 加密
每個加密塊是一個獨立的單元,當拆分后再拼接 不影響其他的加密單元
//AES - ECB 加密
NSString *key = @"LYJ";
//iv 不需要向量
//加密
NSString *reslut = [[EncryptionTools sharedEncryptionTools]encryptString:@"hello" keyString:key iv:nil];
NSLog(@"加密結(jié)果:%@",reslut);
//解密
NSString *decryptString = [[EncryptionTools sharedEncryptionTools]decryptString:reslut keyString:key iv:nil];
NSLog(@"解密結(jié)果:%@",decryptString);
//AES - CBC
加密單元不是獨立,后面的加密依賴前面單元數(shù)據(jù)的加密,更加安全需要向量
//AES - CBC
uint8_t iv[8] = {1,2,3,4,5,6,7,8};
NSData *ivData = [NSData dataWithBytes:iv length:sizeof(iv)];
NSString *CBC_EncryptString = [[EncryptionTools sharedEncryptionTools]encryptString:@"liyanjun" keyString:key iv:ivData];
NSLog(@"CBC加密字符串 %@",CBC_EncryptString);
NSString *CBC_DecryptString = [[EncryptionTools sharedEncryptionTools]decryptString:CBC_EncryptString keyString:key iv:ivData];
NSLog(@"CBC解密字符串 %@",CBC_DecryptString);
des 給工具類單例的一個參數(shù)設(shè)置一下值即可
//DES - ECB
[EncryptionTools sharedEncryptionTools].algorithm = kCCAlgorithmDES;
NSString *DES_ECB_EncryptString = [[EncryptionTools sharedEncryptionTools]encryptString:@"hello" keyString:key iv:nil];
NSLog(@"DES_ECB加密字符串 %@",DES_ECB_EncryptString);
NSString *ECB_CBC_DecryptString = [[EncryptionTools sharedEncryptionTools]decryptString:DES_ECB_EncryptString keyString:key iv:nil];
NSLog(@"DES_ECB解密字符串 %@",ECB_CBC_DecryptString);