美文网首页
iOS - AES加解密 代码记录备忘

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

作者: 林鹏_dev | 来源:发表于2021-08-04 18:56 被阅读0次

    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);
    

    代码实现

    • 注意AES的加密方式:默认是CBC加密方式,EBC方式的加密可以允许不需要IV偏移量
    • 该输出方式为16进制,如果需要base64,可以对应代码注释里面修改(加解密两处处)
    //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;
    }
    
    

    相关文章

      网友评论

          本文标题:iOS - AES加解密 代码记录备忘

          本文链接:https://www.haomeiwen.com/subject/btauvltx.html