iOS对称加密

  • 对称加密 - 传统加密算法##

    • 加密和解密使用同一个"密钥"!
    • 密钥的保密工作就非常的重要!! 密钥会定期更换!密钥的管理很重要!!
  • 经典算法
    • DES 数据加密标准(用的比较少,因为强度不够).
    • 3DES 使用3个密钥,对相同的数据执行三次加密,强度增强.
    • AES 高级加密标准,也是目前使用最多的对称加密算法,目前美国国家安全局使用AES加密,苹果的钥匙串访问就是使用AES加密
  • 两种加密方式 (ECB和CBC)
    • ECB: 电子代码本,就是将一个数据拆分为多块,然后独立加密的!
    • CBC: 密码块链,使用一个密钥和一个初始化"向量"对数据执行加密转换,能保证密文的完整性,如果一个数据发生改变,后面所有的数据将会被破坏!
      向量:某个方向的数量.
      现代的密码学都和几何有关!因为几何(包含圆形\椭圆\球体)的变量是有规律的,但是结果是多变的!
  • 终端测试
    接下来我们分别使用 DES和AES两种算法的两种加密方式来终端测试一下。
/**
 *  终端测试指令
 *
 *  DES(ECB)加密
 *  $ echo -n 加密的内容如:(hello) | openssl enc -des-ecb -K Key的ASCII码如:(abc=616263) -nosalt | base64
 *
 * DES(CBC)加密
 *  $ echo -n 加密的内容如:(hello) | openssl enc -des-cbc -iv 初始化向量(8个字节)如:0102030405060708 -K Key的ASCII码如:(abc=616263) -nosalt | base64
 *
 *  AES(ECB)加密
 *  $ echo -n 加密的内容如:(hello) | openssl enc -aes-128-ecb -K Key的ASCII码如:(abc=616263) -nosalt | base64
 *
 *  AES(CBC)加密
 *  $ echo -n 加密的内容如:(hello) | openssl enc -aes-128-cbc -iv 初始化向量(8个字节)如:0102030405060708 -K Key的ASCII码如:(abc=616263) -nosalt | base64
 *
 *  DES(ECB)解密
 *  $ echo -n 解密的内容如:(HQr0Oij2kbo=) | base64 -D | openssl enc -des-ecb -K Key的ASCII码如:(abc=616263) -nosalt -d
 *
 *  DES(CBC)解密
 *  $ echo -n 解密的内容如:(alvrvb3Gz88=) | base64 -D | openssl enc -des-cbc -iv 初始化向量(8个字节)如:0102030405060708 -K Key的ASCII码如:(abc=616263) -nosalt -d
 *
 *  AES(ECB)解密
 *  $ echo -n 解密的内容如:(d1QG4T2tivoi0Kiu3NEmZQ==) | base64 -D | openssl enc -aes-128-ecb -K Key的ASCII码如:(abc=616263) -nosalt -d
 *
 *  AES(CBC)解密
 *  $ echo -n 解密的内容如:(u3W/N816uzFpcg6pZ+kbdg==) | base64 -D | openssl enc -aes-128-cbc -iv 初始化向量(8个字节)如:0102030405060708 -K Key的ASCII码如:(abc=616263) -nosalt -d
 *
 *  提示:
 *      1> 加密过程是先加密,再base64编码
 *      2> 解密过程是先base64解码,再解密
 */
  • OC中具体的代码实现
    首先新建一个工具类 (EncryptionTools)

    EncryptionTools.h


#import 
#import 

@interface EncryptionTools : NSObject

+ (instancetype)sharedEncryptionTools;

/**
 @constant   kCCAlgorithmAES     高级加密标准,128位(默认)
 @constant   kCCAlgorithmDES     数据加密标准
 */
@property (nonatomic, assign) uint32_t algorithm;

/**
 *  加密字符串并返回base64编码字符串
 *
 *  @param string    要加密的字符串
 *  @param keyString 加密密钥
 *  @param iv        初始化向量(8个字节)
 *
 *  @return 返回加密后的base64编码字符串
 */
- (NSString *)encryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv;

/**
 *  解密字符串
 *
 *  @param string    加密并base64编码后的字符串
 *  @param keyString 解密密钥
 *  @param iv        初始化向量(8个字节)
 *
 *  @return 返回解密后的字符串
 */
- (NSString *)decryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv;

@end

EncryptionTools.m


#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 {
    
    // 设置秘钥
    NSData *keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding];
    uint8_t cKey[self.keySize];
    bzero(cKey, sizeof(cKey));
    [keyData getBytes:cKey length:self.keySize];
    
    // 设置iv
    /*
     kCCOptionPKCS7Padding                      CBC 的加密方式
     kCCOptionPKCS7Padding | kCCOptionECBMode   ECB 的加密方式
     */
    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;
    }
    
    // 设置输出缓冲区
    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
    size_t bufferSize = [data length] + self.blockSize;
    void *buffer = malloc(bufferSize);
    
    // 开始加密
    size_t encryptedSize = 0;
    /***
     CCCrypt 对称加密算法的核心函数(加密/解密)
     参数:
     1.kCCEncrypt  加密/kCCDecrypt 解密
     2.加密算法,默认使用的是  AES/DES
     3.加密选项  ECB/CBC 
         kCCOptionPKCS7Padding                      CBC 的加密方式
         kCCOptionPKCS7Padding | kCCOptionECBMode   ECB 的加密方式
     4.加密密钥
     5.密钥长度
     6.iv 初始化向量,ECB 不需要指定
     7.加密的数据
     8.加密的数据的长度
     9.密文的内存地址
     10.密文缓冲区的大小
     11.加密结果大小
     */
    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(@"[错误] 加密失败|状态编码: %d", cryptStatus);
    }
    
    return [result base64EncodedStringWithOptions:0];
}

- (NSString *)decryptString:(NSString *)string keyString:(NSString *)keyString iv:(NSData *)iv {
    
    // 设置秘钥
    NSData *keyData = [keyString dataUsingEncoding:NSUTF8StringEncoding];
    uint8_t cKey[self.keySize];
    bzero(cKey, sizeof(cKey));
    [keyData getBytes:cKey length:self.keySize];
    
    // 设置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;
    }
    
    // 设置输出缓冲区
    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(@"[错误] 解密失败|状态编码: %d", cryptStatus);
    }
    
    return [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
}

@end

使用工具类加密和解密

    //AES - ECB 加密
    NSString * key = @"hk";
    NSLog(@"加密: %@",[[EncryptionTools sharedEncryptionTools] encryptString:@"hello" keyString:key iv:nil]);
    NSLog(@"解密: %@",[[EncryptionTools sharedEncryptionTools] decryptString:@"cKRPM1ALLG+0q5qCjADoaQ==" keyString:key iv:nil]);
    
    
    
    //AES - CBC 加密
    uint8_t iv[8] = {2,3,4,5,6,7,0,0}; //直接影响加密结果!
    NSData * ivData = [NSData dataWithBytes:iv length:sizeof(iv)];
    NSLog(@"CBC加密: %@",[[EncryptionTools sharedEncryptionTools] encryptString:@"hello" keyString:key iv:ivData]);
    NSLog(@"CBC解密: %@", [[EncryptionTools sharedEncryptionTools] decryptString:@"+dv/u4juE0WE3S9XSFyibA==" keyString:key iv:ivData]);
    
    //DES - ECB 加密
    [EncryptionTools sharedEncryptionTools].algorithm = kCCAlgorithmDES;
    NSLog(@"DES 加密%@",[[EncryptionTools sharedEncryptionTools] encryptString:@"hello" keyString:key iv:nil]);
    NSLog(@"DES 解密: %@", [[EncryptionTools sharedEncryptionTools] decryptString:@"vTuv8E5AlWQ=" keyString:key iv:nil]);

你可能感兴趣的:(iOS对称加密)