iOS開(kāi)發(fā)之AES+Base64數(shù)據(jù)混合加密與解密

allluckly.cn.jpg

"APP的數(shù)據(jù)安全已經(jīng)牽動(dòng)著我們開(kāi)發(fā)者的心,簡(jiǎn)單的MD5/Base64等已經(jīng)難以滿(mǎn)足當(dāng)下的數(shù)據(jù)安全標(biāo)準(zhǔn),本文簡(jiǎn)單的介紹下AES與Base64的混合加密與解密"

AES:高級(jí)加密標(biāo)準(zhǔn)(英語(yǔ):Advanced Encryption Standard,縮寫(xiě):AES)致燥,在密碼學(xué)中又稱(chēng)Rijndael加密法辽剧,是美國(guó)聯(lián)邦政府采用的一種區(qū)塊加密標(biāo)準(zhǔn)臂寝。這個(gè)標(biāo)準(zhǔn)用來(lái)替代原先的DES章鲤,已經(jīng)被多方分析且廣為全世界所使用。經(jīng)過(guò)五年的甄選流程咆贬,高級(jí)加密標(biāo)準(zhǔn)由美國(guó)國(guó)家標(biāo)準(zhǔn)與技術(shù)研究院(NIST)于2001年11月26日發(fā)布于FIPS PUB 197败徊,并在2002年5月26日成為有效的標(biāo)準(zhǔn)。2006年掏缎,高級(jí)加密標(biāo)準(zhǔn)已然成為對(duì)稱(chēng)密鑰加密中最流行的算法之一皱蹦。

以上是來(lái)自百度百科的解釋。

下面我將用代碼來(lái)闡述其使用方法眷蜈。
首先我們創(chuàng)建一個(gè)NSData的類(lèi)擴(kuò)展沪哺,命名為AES,創(chuàng)建完如果對(duì)的話應(yīng)該是這樣的NSData+AES然后導(dǎo)入如下頭文件

#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>



再增加加解密的方法酌儒,方便外部文件的調(diào)用辜妓,寫(xiě)完.h文件如下

#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文件中依次實(shí)現(xiàn)這幾個(gè)方法,具體如下

#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<4; nib++) {

            int byt = (nib == 0)?0:nib-1;

            int ix = (nib+1)*2;

            if (i+byt >= 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


AES+Base64的加密方式到此已經(jīng)結(jié)束了今豆,下面講一下單純的AES字符串加密的嫌拣。

和上面的基本上差不多,寫(xiě)一個(gè)NSString的類(lèi)擴(kuò)展呆躲,命名為AES,創(chuàng)建完如果對(duì)的話應(yīng)該是這樣的NSString+AES導(dǎo)入如下頭文件

#import "NSData+AES.h"



同樣的把加解密的方法寫(xiě)在.h文件中捶索,寫(xiě)完如下

#import <Foundation/Foundation.h>
#import "NSData+AES.h"

@interface NSString (AES)

//加密
- (NSString *) AES256_Encrypt:(NSString *)key;

//解密
- (NSString *) AES256_Decrypt:(NSString *)key;

@end


.m實(shí)現(xiàn)方法

//加密
- (NSString *) AES256_Encrypt:(NSString *)key{
    const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
    NSData *data = [NSData dataWithBytes:cstr length:self.length];
    //對(duì)數(shù)據(jù)進(jìn)行加密
    NSData *result = [data AES256_Encrypt:key];

    //轉(zhuǎn)換為2進(jìn)制字符串
    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:@"%02x", datas[i]];
    }
    return output;
    }
    return nil;
}

//解密
- (NSString *) AES256_Decrypt:(NSString *)key{
    //轉(zhuǎn)換為2進(jìn)制Data
    NSMutableData *data = [NSMutableData dataWithCapacity:self.length / 2];
    unsigned char whole_byte;
    char byte_chars[3] = {'\0','\0','\0'};
    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];
    }

    //對(duì)數(shù)據(jù)進(jìn)行解密
    NSData* result = [data AES256_Decrypt:key];
    if (result && result.length > 0) {
        return [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
    }
    return nil;
}



到此我們加密的文件基本上都已經(jīng)OK了插掂,下面我們來(lái)簡(jiǎn)單的的使用一下,具體如下:

#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是和后臺(tái)約定的key哦腥例,不然無(wú)法解密....

    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


運(yùn)行得到打印的結(jié)果如下:

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是和后臺(tái)約定的key哦辅甥,不然無(wú)法解密....

如后臺(tái)無(wú)法解密可嘗試一下這篇文章的解決方法ios端解密出現(xiàn)無(wú)法解密問(wèn)題的解決方案

最后留下demo下載地址

如對(duì)你有幫助,請(qǐng)不要吝惜你的star和喜歡哦燎竖!

技術(shù)交流群:534926022(免費(fèi)) 511040024(0.8/人付費(fèi))

推薦一款學(xué)習(xí)iOS開(kāi)發(fā)的app_____|______| | 傳送門(mén)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末璃弄,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子构回,更是在濱河造成了極大的恐慌夏块,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纤掸,死亡現(xiàn)場(chǎng)離奇詭異脐供,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)借跪,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)政己,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人掏愁,你說(shuō)我怎么就攤上這事歇由÷央梗” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵沦泌,是天一觀的道長(zhǎng)辽慕。 經(jīng)常有香客問(wèn)我,道長(zhǎng)赦肃,這世上最難降的妖魔是什么溅蛉? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮他宛,結(jié)果婚禮上船侧,老公的妹妹穿的比我還像新娘。我一直安慰自己厅各,他們只是感情好镜撩,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著队塘,像睡著了一般袁梗。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上憔古,一...
    開(kāi)封第一講書(shū)人閱讀 52,457評(píng)論 1 311
  • 那天遮怜,我揣著相機(jī)與錄音,去河邊找鬼鸿市。 笑死锯梁,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的焰情。 我是一名探鬼主播陌凳,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼内舟!你這毒婦竟也來(lái)了合敦?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤验游,失蹤者是張志新(化名)和其女友劉穎充岛,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體批狱,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡裸准,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了赔硫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片炒俱。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出权悟,到底是詐尸還是另有隱情砸王,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布峦阁,位于F島的核電站谦铃,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏榔昔。R本人自食惡果不足惜驹闰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望撒会。 院中可真熱鬧嘹朗,春花似錦、人聲如沸诵肛。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)怔檩。三九已至褪秀,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間薛训,已是汗流浹背媒吗。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留许蓖,地道東北人蝴猪。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像膊爪,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子嚎莉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容