zoukankan      html  css  js  c++  java
  • iOS-AES算法总结

    AESCipher.h

    #import <Foundation/Foundation.h>
    
    @interface AESCipher : NSObject
    
    /**
     加密算法
    
     @param dictionary 待加密字典
     @param key 密钥
     @return 加密后字符串
     */
    + (NSString *)encryptAES:(NSDictionary *)dictionary key:(NSString *)key;
    
    /**
     解密算法
    
     @param content 待解密字符串
     @param key 密钥
     @return 解密后字典
     */
    + (NSDictionary *)decryptAES:(NSString *)content key:(NSString *)key;
    
    @end

    AESCiphser.m

      注意:需要注意的是AES加密算法中的这几个设置参数一定要和服务器端一致,否则会有各种错误

      1)密钥长度(Key Size)

      2)加密模式(Cipher Mode)

      3)填充方式(Padding)

      4)初始向量(Initialization Vector)

    #import "AESCipher.h"
    #import <CommonCrypto/CommonCryptor.h>
    
    /** 初始向量*/
    NSString *const kInitVector = @"16-Bytes--String";
    /** 密钥长度:AES-128*/
    size_t const kKeySize = kCCKeySizeAES128;
    
    @implementation AESCipher
    
    #pragma mark - 加密算法
    
    + (NSString *)encryptAES:(NSDictionary *)dictionary key:(NSString *)key {
        
        // NSDictionary -> NSString
        NSString *content = [self convertToJsonData:dictionary];
        
        // 待加密数据: NSString -> NSData
        NSData *contentData = [content dataUsingEncoding:NSUTF8StringEncoding];
        NSUInteger dataLength = contentData.length;
        
        // 密钥长度:kCCKeySizeAES128
        char keyPtr[kKeySize + 1]; // 为结束符'\0' +1
        memset(keyPtr, 0, sizeof(keyPtr));
        [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
        
        // 密文长度 <= 明文长度 + BlockSize(填充数据)
        size_t encryptSize = dataLength + kCCBlockSizeAES128;
        void *encryptedBytes = malloc(encryptSize);
        size_t actualOutSize = 0;
        
        NSData *initVector = [kInitVector dataUsingEncoding:NSUTF8StringEncoding];
        
        // 设置加密参数
        // 系统默认使用 CBC 加密模式,然后指明使用 PKCS7Padding 补码方式(填充方式)
        CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                              kCCAlgorithmAES,
                                              kCCOptionPKCS7Padding,
                                              keyPtr,
                                              kKeySize,
                                              initVector.bytes,
                                              contentData.bytes,
                                              dataLength,
                                              encryptedBytes,
                                              encryptSize,
                                              &actualOutSize);
        
        if (cryptStatus == kCCSuccess) {
            // 加密结果编码方式: base64 编码
            return [[NSData dataWithBytesNoCopy:encryptedBytes length:actualOutSize] base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
        }
        free(encryptedBytes);
        return nil;
    }
    
    #pragma mark - 解密算法
    
    + (NSDictionary *)decryptAES:(NSString *)content key:(NSString *)key {
        // 把 base64 String 转换成 Data
        NSData *contentData = [[NSData alloc] initWithBase64EncodedString:content options:NSDataBase64DecodingIgnoreUnknownCharacters];
        NSUInteger dataLength = contentData.length;
        
        char keyPtr[kKeySize + 1];
        memset(keyPtr, 0, sizeof(keyPtr));
        [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
        
        size_t decryptSize = dataLength + kCCBlockSizeAES128;
        void *decryptedBytes = malloc(decryptSize);
        size_t actualOutSize = 0;
        
        NSData *initVector = [kInitVector dataUsingEncoding:NSUTF8StringEncoding];
        
        CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                              kCCAlgorithmAES,
                                              kCCOptionPKCS7Padding,
                                              keyPtr,
                                              kKeySize,
                                              initVector.bytes,
                                              contentData.bytes,
                                              dataLength,
                                              decryptedBytes,
                                              decryptSize,
                                              &actualOutSize);
        
        if (cryptStatus == kCCSuccess) {
            NSString *content = [[NSString alloc] initWithData:[NSData dataWithBytesNoCopy:decryptedBytes length:actualOutSize] encoding:NSUTF8StringEncoding];
            return [self dictionaryWithJsonString:content];
        }
        free(decryptedBytes);
        return nil;
    }
    
    #pragma mark - NSDictionary <-> NSString
    
    // NSDictionary 转换为 NSString
    + (NSString *)convertToJsonData:(NSDictionary *)dictionary {
        NSError *error;
        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dictionary options:NSJSONWritingPrettyPrinted error:&error];
        NSString *jsonString;
        if (!jsonData) {
            NSLog(@"%@",error);
        }else{
            jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
        }
        NSMutableString *mutStr = [NSMutableString stringWithString:jsonString];
        NSRange range = {0,jsonString.length};
        //去掉字符串中的空格
        [mutStr replaceOccurrencesOfString:@" " withString:@"" options:NSLiteralSearch range:range];
        NSRange range2 = {0,mutStr.length};
        //去掉字符串中的换行符
        [mutStr replaceOccurrencesOfString:@"
    " withString:@"" options:NSLiteralSearch range:range2];
        return mutStr;
    }
    
    // NSString 转换为 NSDictionary
    + (NSDictionary *)dictionaryWithJsonString:(NSString *)content {
        if (content == nil) {
            return nil;
        }
        
        NSData *jsonData = [content dataUsingEncoding:NSUTF8StringEncoding];
        NSError *err;
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
                                                            options:NSJSONReadingMutableContainers
                                                              error:&err];
        if(err)
        {
            NSLog(@"json解析失败:%@",err);
            return nil;
        }
        return dic;
    }
    
    @end

    加密方法的调用(key--密钥,一定要确保是16位的,且和服务端一致)

    NSDictionary *dictionary = @{
                                   @"key":@"value"
                                    };
    NSString *key = @"1234567890123456";
    NSString *cipherString = [AESCipher encryptAES:dictionary key:key];

    解密方法的调用

    NSDictionary *dictionary = [AESCipher decryptAES:cipherString key:key];
  • 相关阅读:
    python的filter函数的使用方法详解以及使用案例,是否以什么结尾,是否大于什么(判断是True,则留下来)
    python的reduce函数的使用方法详解以及使用案例,相加,相乘(处理一个序列,然后把序列进程合并操作)
    python的map函数的使用方法详解以及使用案例(处理每个元素的自增、自减、平方等)
    python的匿名函数 lambda的使用方法详解以及使用案例
    python函数的 全局变量与局部变量
    python的函数介绍 位置参数 关键字参数 默认参数 参数组 *args **kwargs
    python set() 集合的添加删除、交集、并集、差集、交叉补集、集合的方法介绍以及使用案例
    python的dict()字典数据类型的方法详解以及案例使用
    python的tuple()元组数据类型的使用方法以及案例
    MATLAB分类与预测算法函数
  • 原文地址:https://www.cnblogs.com/widgetbox/p/11584843.html
Copyright © 2011-2022 走看看