iOS - AES加解密 代码记录备忘

2021-08-04  本文已影响0人  林鹏_dev

AES加解密

在线AES加解密验证

IOS项目的Utils工具类里面暴露两个方法

//MARK: AES加解密
+ (NSString *)aesEncrypt:(NSString *)sourceStr;

+ (NSString *)aesDecrypt:(NSString *)secretStr;

跟其他端确定秘钥和偏移量

#define GL_AES_KEY                  @"aef01238765abcde"
#define GL_AES_IV                      GL_AES_KEY

核心逻辑

   加解密: kCCEncrypt - 加密,kCCDecrypt - 解密  
   填充:kCCOptionPKCS7Padding
   加密方式:
    /*
     //CBC模式
     kCCOptionPKCS7Padding
     //ECB模式
     kCCOptionPKCS7Padding  |  kCCOptionECBMode
     */

CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          kCCAlgorithmAES128,
                                          kCCOptionPKCS7Padding,
                                          keyPtr,
                                          kCCBlockSizeAES128,
                                          ivPtr,//ECB模式下可以为NULL
                                          [sourceData bytes],
                                          dataLength,
                                          buffer,
                                          buffersize,
                                          &numBytesEncrypted);

代码实现

//MARK: AES加解密相关 start
+ (NSString *)aesEncrypt:(NSString *)sourceStr {
    if (!sourceStr) {
        return nil;
    }
    
    //秘钥
    char keyPtr[kCCKeySizeAES256 + 1];
    bzero(keyPtr, sizeof(keyPtr));
    [GL_AES_KEY getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
     
    //向量
    char ivPtr[kCCBlockSizeAES128 + 1];
    bzero(ivPtr, sizeof(ivPtr));
    [GL_AES_IV getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
    
    NSData *sourceData = [sourceStr dataUsingEncoding:NSUTF8StringEncoding];
    NSUInteger dataLength = [sourceData length];
    size_t buffersize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(buffersize);
    size_t numBytesEncrypted = 0;
    /*
     //CBC模式
     kCCOptionPKCS7Padding
     //ECB模式
     kCCOptionPKCS7Padding | kCCOptionECBMode
     */
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          kCCAlgorithmAES128,
                                          kCCOptionPKCS7Padding,
                                          keyPtr,
                                          kCCBlockSizeAES128,
                                          ivPtr,//ECB模式下可以为NULL
                                          [sourceData bytes],
                                          dataLength,
                                          buffer,
                                          buffersize,
                                          &numBytesEncrypted);
     
    if (cryptStatus == kCCSuccess) {
        NSData *encryptData = [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
        //对加密后的二进制数据进行base64转码
        //return [encryptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
        
        //转换为16进制字符串
        NSMutableString *output = [NSMutableString stringWithCapacity:encryptData.length * 2];
        if (encryptData && encryptData.length > 0) {
            Byte *datas = (Byte*)[encryptData bytes];
            for(int i = 0; i < encryptData.length; i++){
                [output appendFormat:@"%02x", datas[i]];
            }
        }
        return output;
        
    } else {
        free(buffer);
        return nil;
    }
}

+ (NSString *)aesDecrypt:(NSString *)secretStr {
    if (!secretStr) {
        return nil;
    }
    //先对加密的字符串进行base64解码
    //NSData *decodeData = [[NSData alloc] initWithBase64EncodedString:secretStr options:NSDataBase64DecodingIgnoreUnknownCharacters];
  //先对加密的字符串进行16进制解码
    NSData *decodeData = [self convertHexStrToData:secretStr];
    
    //秘钥
    char keyPtr[kCCKeySizeAES256 + 1];
    bzero(keyPtr, sizeof(keyPtr));
    [GL_AES_KEY getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
     
    //向量
    char ivPtr[kCCBlockSizeAES128 + 1];
    bzero(ivPtr, sizeof(ivPtr));
    [GL_AES_IV getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
     
    NSUInteger dataLength = [decodeData length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    size_t numBytesDecrypted = 0;
    /*
     //CBC模式
     kCCOptionPKCS7Padding
     //ECB模式
     kCCOptionPKCS7Padding | kCCOptionECBMode
     */
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                          kCCAlgorithmAES128,
                                          kCCOptionPKCS7Padding,
                                          keyPtr,
                                          kCCBlockSizeAES128,
                                          ivPtr,//ECB模式下可以为NULL
                                          [decodeData bytes],
                                          dataLength,
                                          buffer,
                                          bufferSize,
                                          &numBytesDecrypted);
    if (cryptStatus == kCCSuccess) {
        NSData *data = [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
        NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        return result;
    } else {
        free(buffer);
        return nil;
    }
}

// 16进制转NSData
+ (NSData *)convertHexStrToData:(NSString *)str {
    if (!str || [str length] == 0) {
        return nil;
    }
    
    NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:20];
    NSRange range;
    if ([str length] % 2 == 0) {
        range = NSMakeRange(0, 2);
    } else {
        range = NSMakeRange(0, 1);
    }
    for (NSInteger i = range.location; i < [str length]; i += 2) {
        unsigned int anInt;
        NSString *hexCharStr = [str substringWithRange:range];
        NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr];
        
        [scanner scanHexInt:&anInt];
        NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];
        [hexData appendData:entity];
        
        range.location += range.length;
        range.length = 2;
    }
    return hexData;
}

上一篇下一篇

猜你喜欢

热点阅读