当前位置 : 主页 > 手机开发 > ios >

iOS-AES算法总结

来源:互联网 收集:自由互联 发布时间:2021-06-11
AESCipher.h #import Foundation/Foundation.h @interface AESCipher : NSObject /* * 加密算法 @param dictionary 待加密字典 @param key 密钥 @return 加密后字符串 */ + (NSString *)encryptAES:(NSDictionary *)dictionary key:(NSStrin

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:@"\n" 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];
网友评论