zoukankan      html  css  js  c++  java
  • iOS开发之 AES+Base64数据混合加密与解密

     

    2016-04-08 09:03 编辑: liubinqww 分类:iOS开发 来源:liubinqww 投稿
    889
     
     

    1.jpg

    "APP的数据安全已经牵动着我们开发者的心,简单的MD5/Base64等已经难以满足当下的数据安全标准,本文简单的介绍下AES与Base64的混合加密与解密"

    AES:高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。

    以上是来自百度百科的解释。

    下面我将用代码来阐述其使用方法。 首先我们创建一个NSData的类扩展,命名为AES,创建完如果对的话应该是这样的NSData+AES然后导入如下头文件

    1
    2
    #import 《CommonCrypto/CommonDigest.h》
    #import 《CommonCrypto/CommonCryptor.h》

    再增加加解密的方法,方便外部文件的调用,写完.h文件如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #import 《Foundation/Foundation.h》
    #import 《CommonCrypto/CommonDigest.h》
    #import 《CommonCrypto/CommonCryptor.h》
    @interface NSData (AES)
    //加密
    - (NSData *) AES256_Encrypt:(NSString *)key;
    //解密
    - (NSData *) AES256_Decrypt:(NSString *)key;
    //追加64编码
    - (NSString *)newStringInBase64FromData;
    //同上64编码
    + (NSString*)base64encode:(NSString*)str;
    @end

    .m文件中依次实现这几个方法,具体如下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    #import "NSData+AES.h"static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
     
    @implementation NSData (AES)
     
    //加密
    - (NSData *) AES256_Encrypt:(NSString *)key{
        char keyPtr[kCCKeySizeAES256+1];
        bzero(keyPtr, sizeof(keyPtr));
        [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, kCCBlockSizeAES128,
        NULL,
        [self bytes], dataLength,
        buffer, bufferSize,
        &numBytesEncrypted);
        if (cryptStatus == kCCSuccess) {
            return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
        }
        free(buffer);
        return nil;}
         
        //解密- (NSData *) AES256_Decrypt:(NSString *)key{
     
        char keyPtr[kCCKeySizeAES256+1];
        bzero(keyPtr, sizeof(keyPtr));
        [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, kCCBlockSizeAES128,
        NULL,
        [self bytes], dataLength,
        buffer, bufferSize,
        &numBytesDecrypted);
        if (cryptStatus == kCCSuccess) {
            return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
     
        }
        free(buffer);
        return nil;}
         
        //追加64编码- (NSString *)newStringInBase64FromData            {
     
        NSMutableString *dest = [[NSMutableString alloc] initWithString:@""];
     
        unsigned char * working = (unsigned char *)[self bytes];
     
        int srcLen = (int)[self length];
     
        for (int i=0; i<srclen; i += 3) {         for (int nib="0; nib= srcLen) break;"             unsigned char curr =" ((working[i+byt] << (8-ix)) & 0x3F);"             if (i+nib < srclen) curr |=" ((working[i+nib] ">> ix) & 0x3F);
     
                [dest appendFormat:@"%c", base64[curr]];
     
            }
     
        }
     
        return dest;}
         
        + (NSString*)base64encode:(NSString*)str{
     
        if ([str length] == 0)
     
        return @"";
     
        const char *source = [str UTF8String];
     
        int strlength  = (int)strlen(source);
     
        char *characters = malloc(((strlength + 2) / 3) * 4);
     
        if (characters == NULL)
     
        return nil;
     
        NSUInteger length = 0;
     
        NSUInteger i = 0;
     
        while (i < strlength) {
     
            char buffer[3] = {0,0,0};
     
            short bufferLength = 0;
     
            while (bufferLength < 3 && i < strlength)
     
            buffer[bufferLength++] = source[i++];
     
            characters[length++] = base64[(buffer[0] & 0xFC) >> 2];
     
            characters[length++] = base64[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)];
     
            if (bufferLength > 1)
     
            characters[length++] = base64[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)];
     
            else characters[length++] = '=';
     
            if (bufferLength > 2)
     
            characters[length++] = base64[buffer[2] & 0x3F];
     
            else characters[length++] = '=';
     
        }
     
        NSString *g = [[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSASCIIStringEncoding freeWhenDone:YES];
     
     
        return g;}
         
        @end</srclen; i += 3) {>

    AES+Base64的加密方式到此已经结束了,下面讲一下单纯的AES字符串加密的。
    和上面的基本上差不多,写一个NSString的类扩展,命名为AES,创建完如果对的话应该是这样的NSString+AES导入如下头文件

    1
    #import "NSData+AES.h"


    同样的把加解密的方法写在.h文件中,写完如下

    1
    2
    3
    4
    5
    6
    7
    8
    #import 《Foundation/Foundation.h》
    #import "NSData+AES.h"
    @interface NSString (AES)
    //加密
    - (NSString *) AES256_Encrypt:(NSString *)key;
    //解密
    - (NSString *) AES256_Decrypt:(NSString *)key;
    @end

    .m实现方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    //加密
    - (NSString *) AES256_Encrypt:(NSString *)key{
        const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
        NSData *data = [NSData dataWithBytes:cstr length:self.length];
        //对数据进行加密
        NSData *result = [data AES256_Encrypt:key];
     
        //转换为2进制字符串
        if (result && result.length > 0) {
     
        Byte *datas = (Byte*)[result bytes];
        NSMutableString *output = [NSMutableString stringWithCapacity:result.length * 2];
        for(int i = 0; i < result.length; i++){
            [output appendFormat:@"x", datas[i]];
        }
        return output;
        }
        return nil;
    }
     
    //解密
    - (NSString *) AES256_Decrypt:(NSString *)key{
        //转换为2进制Data
        NSMutableData *data = [NSMutableData dataWithCapacity:self.length / 2];
        unsigned char whole_byte;
        char byte_chars[3] = {'','',''};
        int i;
        for (i=0; i < [self length] / 2; i++) {
        byte_chars[0] = [self characterAtIndex:i*2];
        byte_chars[1] = [self characterAtIndex:i*2+1];
        whole_byte = strtol(byte_chars, NULL, 16);
        [data appendBytes:&whole_byte length:1];
        }
     
        //对数据进行解密
        NSData* result = [data AES256_Decrypt:key];
        if (result && result.length > 0) {
            return [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
        }
        return nil;
    }


    到此我们加密的文件基本上都已经OK了,下面我们来简单的的使用一下,具体如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    #import "ViewController.h"
    #import "NSString+AES.h"@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        //字符串加密    NSString *key = @"12345678";//Key是和后台约定的key哦,不然无法解密....
        NSString *secret = @"aes Bison base64";
     
     
        NSLog(@"字符串加密---%@",[secret AES256_Encrypt:key]);
     
        //字符串解密    NSLog(@"字符串解密---%@",[[secret AES256_Encrypt:key] AES256_Decrypt:key]);
     
     
        //NSData加密+base64
        NSData *plain = [secret dataUsingEncoding:NSUTF8StringEncoding];
     
        NSData *cipher = [plain AES256_Encrypt:key];
     
        NSLog(@"NSData加密+base64++++%@",[cipher newStringInBase64FromData]);
     
     
        //解密
        plain = [cipher AES256_Decrypt:key];
     
        NSLog(@"NSData解密+base64++++%@", [[NSString alloc] initWithData:plain encoding:NSUTF8StringEncoding]);}@end

    运行得到打印的结果如下:

    2016-03-30 17:31:55.686 AES_256[14242:198853] 字符串加密---07815ca46d20acc3ba4e43d6930c7537496e851a36dbeac34fa30c5796089b02
    2016-03-30 17:31:55.687 AES_256[14242:198853] 字符串解密---aes Bison base64
    2016-03-30 17:31:55.687 AES_256[14242:198853] NSData加密+base64++++B4FcpG0grMO6TkPWkwx1N0luhRo22+rDT6MMV5YImwI
    2016-03-30 17:31:55.687 AES_256[14242:198853] NSData解密+base64++++aes Bison base64

    ##值得注意的是Key是和后台约定的key哦,不然无法解密….

    最后留下demo下载地址

     
     
  • 相关阅读:
    C# 从服务器下载文件
    不能使用联机NuGet 程序包
    NPOI之Excel——合并单元格、设置样式、输入公式
    jquery hover事件中 fadeIn和fadeOut 效果不能及时停止
    UVA 10519 !! Really Strange !!
    UVA 10359 Tiling
    UVA 10940 Throwing cards away II
    UVA 10079 Pizze Cutting
    UVA 763 Fibinary Numbers
    UVA 10229 Modular Fibonacci
  • 原文地址:https://www.cnblogs.com/lan1x/p/5370372.html
Copyright © 2011-2022 走看看