IOS AES加密

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IOS AES加密相关的知识,希望对你有一定的参考价值。

参考技术A AES加密有四种工作模式:ECB、CBC、CFB和OFB,其中ios支持ECB(kCCOptionPKCS7Padding 对应Java中的kCCOptionPKCS5Padding)和CBC(kCCOptionECBMode)

AES是开发中常用的加密算法之一。然而由于前后端开发使用的语言不统一,导致经常出现前端加密而后端不能解密的情况出现。然而无论什么语言系统,AES的算法总是相同的, 因此导致结果不一致的原因在于 加密设置的参数不一致 。于是先来看看在两个平台使用AES加密时需要统一的几个参数。

参考: https://welkinx.com/2016/07/30/10/

ios中使用AES128位 ECB模式加密 结果转换16进制

https://tieba.baidu.com/p/4581819586

与服务器通讯的时候,除了确定密钥外,加密模式和填充方式也要确定。第一个例子中,就是使用了kCCOptionPKCS7Padding加密模式,并且有IV(初始向量),而第二个例子中使用了ECB(没有补码方式)。

此外也要注意转码后的密文是转成16进制,还是base64编码。

参考链接:
http://blog.51cto.com/ciphertext/1420338
https://welkinx.com/2016/07/30/10/
https://tieba.baidu.com/p/4581819586

iOS DES,AES加密

最近在准备面试,发现之前项目中用到的加密技术都记得不清楚了,所以总结一下。之前项目用到的加密技术一种是DES加密,用来加密发送请求的字段,保证服务器数据的安全,一种是AES加密,用于加密登录时发送的账号密码数据。

一 . DES加密

DES加密属于对称加密算法,即信息的发送者与接受者在进行信息的传输与处理上使用的同一秘钥。

直接上代码,新建DESEncry文件,.h文件中:

 

#import <Foundation/Foundation.h>

 

@interface DESEncry : NSObject

/**

 * @brief 对文本进行DES加密

 *

 * @param data    待加密的文本数据

 * @param key 加密所有的公钥

 * @param iv 加密向量

 *

 * @return 加密好的数据

 */

+ (NSData *)encryptUseDES:(NSString *)string key:(NSString *)key iv:(const void *)iv;

/**

 * @brief 对文本进行DES解密

 *

 * @param data    待解密的数据

 * @param key 解密所用的公钥

 *

 * @return 解密好的数据

 */

+ (NSData *)DESDecrypt:(NSData *)data WithKey:(NSString *)key;

@end

 

 

.m文件:

#import "DESEncry.h"

#import <CommonCrypto/CommonCryptor.h>

 

@implementation DESEncry

+ (NSData *)encryptUseDES:(NSString *)string key:(NSString *)key iv:(const void *)iv

{

    const char *textBytes = [string UTF8String];

    NSUInteger dataLength = strlen(textBytes);

    NSMutableData *data = [NSMutableData new];

    

    NSUInteger n = dataLength / 1024;

    for (int i = 0; i <= n;i++){

        unsigned char buffer[1024];

        unsigned char temp[1024];

        memset(buffer, 0, sizeof(char));

        memset(temp, 0, sizeof(char));

        strncpy((char*)temp,textBytes, i==n?dataLength-1024*n:1024);

        size_t numBytesEncrypted = 0;

        CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,

                                              kCCOptionPKCS7Padding|kCCOptionECBMode,

                                              [key UTF8String], kCCKeySizeDES,

                                              iv,

                                              temp, i==n?dataLength-1024*n:1024,

                                              buffer, 1024,

                                              &numBytesEncrypted);

        

        if (cryptStatus == kCCSuccess) {

            [data appendData:[NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted]];

        }

        

    }

    return data;

}

+ (NSData *)DESDecrypt:(NSData *)data WithKey:(NSString *)key

{

    char keyPtr[kCCKeySizeAES256+1];

    bzero(keyPtr, sizeof(keyPtr));

    

    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    

    NSUInteger dataLength = [data length];

    

    size_t bufferSize = dataLength + kCCBlockSizeAES128;

    void *buffer = malloc(bufferSize);

    

    size_t numBytesDecrypted = 0;

    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmDES,

                                          kCCOptionPKCS7Padding | kCCOptionECBMode,

                                          keyPtr, kCCBlockSizeDES,

                                          NULL,

                                          [data bytes], dataLength,

                                          buffer, bufferSize,

                                          &numBytesDecrypted);

    

    if (cryptStatus == kCCSuccess) {

        return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];

    }

    

    free(buffer);

    return nil;

}

@end

 

   项目中具体调用:

 NSString *str=HOST;

    _hostUrl = [str stringByAppendingString:@"opt=click&page=Login"];

    NSDictionary * resultdic  = @{@"pwd":pwd,@"uid":uid};

    NSString *strReq = [TypeConversion jsonStringWithDictionary:resultdic];

    //加密

    Byte iv[] = {1,2,3,4,5,6,7,8};

    NSData * data = [DESEncry encryptUseDES:strReq key:@"zywl9876" iv:iv];

    NSString *str5 = [[NSString alloc] initWithData:[GTMBase64 encodeData:data] encoding:NSUTF8StringEncoding];

    

    _paramDict = @{@"_json":str5};

 

二 . AES加密

AES也是属于对称加密算法,不过安全级别比DES高。

上代码,新建MySecurity文件,.h文件中

 

#import <Foundation/Foundation.h>

 

@interface MySecurity : NSObject

#pragma mark -根据密匙初始化

-(instancetype) initWithKey:(NSString *) key;

 

#pragma mark -加密

-(NSString *) AES256EncryptWithString:(NSString *) str;

 

#pragma mark -解密

-(NSString *) AES256DecryptWithString:(NSString *) str;

 

#pragma mark -获取安全密匙

+(NSString*) getSecurityKey;

@end

 

.m文件:

#import "MySecurity.h"

#import "NSData+AES256.h"

@interface MySecurity ()

@property(strong,nonatomic) NSString *key;

 

@end

@implementation MySecurity

#pragma mark -获取安全钥匙

+(NSString*) getSecurityKey

{

    return @"KEY";

}

 

#pragma mark -更加密码密匙初始化

-(instancetype) initWithKey:(NSString *) key

{

    self = [super init];

    if (self)

    {

        self.key = key;

    }

    return self;

}

 

#pragma mark -加密

-(NSString *) AES256EncryptWithString:(NSString *) str

{

    NSData *dt1 = [str dataUsingEncoding:NSUTF8StringEncoding];

    

    NSData *dt2 = [dt1 AES256EncryptWithKey:self.key];

    

    NSString *str2 = [dt2 base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];

    return str2;

}

 

#pragma mark -解密

-(NSString *) AES256DecryptWithString:(NSString *) str

{

    NSData *dt3 = [[NSData alloc] initWithBase64EncodedString:str options:NSDataBase64DecodingIgnoreUnknownCharacters];

    

    NSData *dt4 = [dt3 AES256DecryptWithKey:self.key];

    

    NSString *str4 = [[NSString alloc] initWithData:dt4 encoding:NSUTF8StringEncoding];

    return str4;

}

 新建一个NSData的类别:

#import <Foundation/Foundation.h>

 

@interface NSData (AES256)

/*

 加密

 (NSString*)key 32位秘钥

 返回加密后的 NSData

 */

- (NSData*)AES256EncryptWithKey:(NSString*)key ;

 

/*

 解密

 (NSString*)key 32位秘钥

 返回解密后的 NSData

 */

- (NSData*)AES256DecryptWithKey:(NSString*)key ;

@end

 

 

.m文件

#import "NSData+AES256.h"

#import <CommonCrypto/CommonCryptor.h>

 

@implementation NSData (AES256)

- (NSData*)AES256EncryptWithKey:(NSString*)key {

    

    char keyPtr[kCCKeySizeAES256 +1]; // room for terminator (unused)

    bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)

    

    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    

    NSUInteger dataLength = [self length];

    

    size_t bufferSize           = dataLength + kCCBlockSizeAES128;

    void* buffer                = malloc(bufferSize);

    

    size_t numBytesEncrypted    = 0;

    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,

                                          kCCAlgorithmAES128,

                                          kCCOptionPKCS7Padding|kCCOptionECBMode,

                                          keyPtr,

                                          kCCKeySizeAES256,

                                          NULL /* initialization vector (optional) */,

                                          [self bytes],

                                          dataLength, /* input */

                                          buffer,

                                          bufferSize, /* output */

                                          &numBytesEncrypted);

    

    

    

    if (cryptStatus == kCCSuccess) {

        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];

    }

    

    free(buffer);

    return nil;

}

 

- (NSData*)AES256DecryptWithKey:(NSString*)key {

    

    char keyPtr[kCCKeySizeAES256+1 ]; // room for terminator (unused)

    bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)

    

    

    // fetch key data

    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];

    

    NSUInteger dataLength = [self length];

    

    size_t bufferSize           = dataLength + kCCBlockSizeAES128;

    void* buffer                = malloc(bufferSize);

    

    size_t numBytesDecrypted    = 0;

    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,

                                          kCCAlgorithmAES128,

                                          kCCOptionPKCS7Padding|kCCOptionECBMode,

                                          keyPtr,

                                          kCCKeySizeAES256,

                                          NULL /* initialization vector (optional) */,

                                          [self bytes],

                                          dataLength, /* input */

                                          buffer,

                                          bufferSize, /* output */

                                          &numBytesDecrypted);

    

    if (cryptStatus == kCCSuccess) {

        return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];

    }

    

    free(buffer); //free the buffer;

    return nil;

}

@end

 

项目中的具体调用:

    MySecurity *security = [[MySecurity alloc] initWithKey:[MySecurity getSecurityKey]];

    //AES加密

    NSMutableDictionary*dic = [[NSMutableDictionary alloc]initWithObjectsAndKeys:self.userTF.text,@"LoginName",self.pswTF.text,@"Password", nil];

    NSData*data = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:nil];

    NSString*dataStr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];

    NSString * str1 = [security AES256EncryptWithString:dataStr];

 

以上是关于IOS AES加密的主要内容,如果未能解决你的问题,请参考以下文章

iOS DES,AES加密

iOS开发--AES加密中的那些坑

IOS AES加密之ECB128模式

iOS之AES加密解密

iOS 中的 AES256 NSString 加密

iOS AES的加密解密