iOS下 AES128加密算法獲取動態(tài)密碼的實現(xiàn)

首先我們來看項目需求:


這是一款脫機門禁的設(shè)備,后臺會給我們返回機器序列號和密鑰,但是后臺只會給我們返回6個字節(jié)的密鑰和6個字節(jié)的機器序列號,首先我們需要將6個字節(jié)的密鑰補齊為16字節(jié)

//判斷秘鑰長度 不夠32位后面補0
這里的self.OfflineKey存儲的是我獲取的密鑰
self.OfflineKeyStr 是要加密之前補齊16字節(jié)的密鑰
    if ([self.OfflineKey length] < 32) {
        NSString *str = [self.OfflineKey stringByPaddingToLength:32 withString:@"0" startingAtIndex:0];
        self.OfflineKeyStr = str;
    }

因為是動態(tài)密碼,所以這里根據(jù)的是時間的變化改變密碼的值
這里的self.OfflineNum存儲的是我獲取的機身號
self.OfflineNumStr 是要加密之前補齊16字節(jié)的時間+機身號

NSDate *date =[NSDate date];
    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
    [formatter setDateFormat:@"yy"];
    NSInteger currentYear=[[formatter stringFromDate:date] integerValue];
    [formatter setDateFormat:@"MM"];
    NSInteger currentMonth=[[formatter stringFromDate:date]integerValue];
    [formatter setDateFormat:@"dd"];
    NSInteger currentDay=[[formatter stringFromDate:date] integerValue];
    NSLog(@"currentDate = %@ ,year = %.2ld ,month=%.2ld, day=%.2ld",date,currentYear,currentMonth,currentDay);

    NSString *originalStr= [NSString stringWithFormat:@"%.2ld%.2ld%.2ld%@",currentYear,currentMonth,currentDay,self.OfflineNum];
    //判斷機身號+長度 不夠32位后面補0
    if ([originalStr length] < 32) {
        NSString *str = [originalStr stringByPaddingToLength:32 withString:@"0" startingAtIndex:0];
        self.OfflineNumStr = str;
    }

到目前為止 我們已經(jīng)準備好了要加密的數(shù)據(jù)
下面準備進行AES 128加密
首先我們新建一個類
.h

//
//  AES128Util.h
//
//

#import <Foundation/Foundation.h>

@interface AES128Util : NSObject


+(NSString *)AES128Encrypt:(NSString *)plainText key:(NSString *)key;


+(NSString *)AES128Decrypt:(NSString *)encryptText key:(NSString *)key;


+ (NSData*)dataForHexString:(NSString*)hexString;
@end

.m

//
//  AES128Util.m
//  
//


#import "AES128Util.h"
#import <CommonCrypto/CommonCryptor.h>

@implementation AES128Util


+(NSString *)AES128Encrypt:(NSString *)hexStringData key:(NSString *)hexStringKey
{
    NSData *keyData = [self dataForHexString:hexStringKey];
    char *keyPtr = (char *)[keyData bytes];
    
    NSData* data = [self dataForHexString:hexStringData];
    NSUInteger dataLength = [data length];
    char *dataPtr=(char *)[data bytes];
    
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                          kCCAlgorithmAES128,
                                          kCCOptionECBMode,
                                          keyPtr,
                                          kCCBlockSizeAES128,
                                          NULL,
                                          dataPtr,
                                          dataLength,
                                          buffer,
                                          bufferSize,
                                          &numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        NSData *resultData = [NSData dataWithBytes:buffer length:numBytesEncrypted];
        free(buffer);
        return [self hexStringFromData:resultData];
    }
    
    free(buffer);
    return nil;
}




+(NSString *)AES128Decrypt:(NSString *)hexStringData key:(NSString *)hexStringKey
{
    NSData *keyData = [self dataForHexString:hexStringKey];
    char *keyPtr = (char *)[keyData bytes];
    
    NSData* data = [self dataForHexString:hexStringData];
    NSUInteger dataLength = [data length];
    char *dataPtr=(char *)[data bytes];
    
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    size_t numBytesCrypted = 0;
    
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                          kCCAlgorithmAES128,
                                          kCCOptionECBMode,
                                          keyPtr,
                                          kCCBlockSizeAES128,
                                          NULL,
                                          dataPtr,
                                          dataLength,
                                          buffer,
                                          bufferSize,
                                          &numBytesCrypted);
    if (cryptStatus == kCCSuccess) {
        NSData *resultData = [NSData dataWithBytes:buffer length:numBytesCrypted];
        free(buffer);
        return [self hexStringFromData:resultData];
    }
    free(buffer);
    return nil;
}


// 普通字符串轉(zhuǎn)換為十六進
+ (NSString *)hexStringFromData:(NSData *)data {
    Byte *bytes = (Byte *)[data bytes];
    // 下面是Byte 轉(zhuǎn)換為16進制躁垛。
    NSString *hexStr = @"";
    for(int i=0; i<[data length]; i++) {
        NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i] & 0xff]; //16進制數(shù)
        newHexStr = [newHexStr uppercaseString];
        
        if([newHexStr length] == 1) {
            newHexStr = [NSString stringWithFormat:@"0%@",newHexStr];
        }
        
        hexStr = [hexStr stringByAppendingString:newHexStr];
        
    }
    return hexStr;
}


//參考:http://blog.csdn.net/linux_zkf/article/details/17124577
//十六進制轉(zhuǎn)Data
+ (NSData*)dataForHexString:(NSString*)hexString
{
    if (hexString == nil) {
        
        return nil;
    }
    
    const char* ch = [[hexString lowercaseString] cStringUsingEncoding:NSUTF8StringEncoding];
    NSMutableData* data = [NSMutableData data];
    while (*ch) {
        if (*ch == ' ') {
            continue;
        }
        char byte = 0;
        if ('0' <= *ch && *ch <= '9') {
            
            byte = *ch - '0';
        }else if ('a' <= *ch && *ch <= 'f') {
            
            byte = *ch - 'a' + 10;
        }else if ('A' <= *ch && *ch <= 'F') {
            
            byte = *ch - 'A' + 10;
            
        }
        
        ch++;
        
        byte = byte << 4;
        
        if (*ch) {
            
            if ('0' <= *ch && *ch <= '9') {
                
                byte += *ch - '0';
                
            } else if ('a' <= *ch && *ch <= 'f') {
                
                byte += *ch - 'a' + 10;
                
            }else if('A' <= *ch && *ch <= 'F'){
                
                byte += *ch - 'A' + 10;
                
            }
            
            ch++;
            
        }
        
        [data appendBytes:&byte length:1];
        
    }
    
    return data;
}


@end

加密

//加密
    NSString *encryStr = [AES128Util AES128Encrypt:self.OfflineNumStr key:self.OfflineKeyStr];
    //轉(zhuǎn)為16字節(jié)
    NSData *data = [AES128Util dataForHexString:encryStr];
    //截取后三個字節(jié)
    NSData *last3data = [data subdataWithRange:NSMakeRange(data.length-3, 3)];
    //變?yōu)閕nt整形
    Byte *bytes = (Byte *)[last3data bytes];
    int i = ((bytes[0] & 0x000000ff) << 16) | ((bytes[1] & 0x000000ff) << 8) | (bytes[2] & 0x000000ff);
    
    NSString *result = [NSString stringWithFormat:@"%04d",i];
    if (result.length>4) {
        result = [result substringFromIndex:result.length-4];
    }
    NSLog(@"動態(tài)碼==%@",result);

這里拿到的動態(tài)碼就是最終我們需要的動態(tài)密碼,因為我們加密只到天,所以密碼是一天一變.

特別感謝簡書-iOS開發(fā)交流群 群號:361736344 中深圳-標哥 的幫助(這里就不泄露QQ了 感興趣的可以加群找他)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末园蝠,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子九榔,更是在濱河造成了極大的恐慌,老刑警劉巖婴栽,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件食侮,死亡現(xiàn)場離奇詭異,居然都是意外死亡绕娘,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門栽连,熙熙樓的掌柜王于貴愁眉苦臉地迎上來险领,“玉大人,你說我怎么就攤上這事秒紧【钅埃” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵熔恢,是天一觀的道長脐湾。 經(jīng)常有香客問我,道長叙淌,這世上最難降的妖魔是什么秤掌? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮鹰霍,結(jié)果婚禮上闻鉴,老公的妹妹穿的比我還像新娘。我一直安慰自己茂洒,他們只是感情好孟岛,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般蚀苛。 火紅的嫁衣襯著肌膚如雪在验。 梳的紋絲不亂的頭發(fā)上玷氏,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天堵未,我揣著相機與錄音,去河邊找鬼盏触。 笑死渗蟹,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的赞辩。 我是一名探鬼主播雌芽,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼辨嗽!你這毒婦竟也來了世落?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤糟需,失蹤者是張志新(化名)和其女友劉穎屉佳,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體洲押,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡武花,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了杈帐。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片体箕。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖挑童,靈堂內(nèi)的尸體忽然破棺而出累铅,到底是詐尸還是另有隱情,我是刑警寧澤站叼,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布争群,位于F島的核電站,受9級特大地震影響大年,放射性物質(zhì)發(fā)生泄漏换薄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一翔试、第九天 我趴在偏房一處隱蔽的房頂上張望轻要。 院中可真熱鬧,春花似錦垦缅、人聲如沸冲泥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽凡恍。三九已至志秃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間嚼酝,已是汗流浹背浮还。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留闽巩,地道東北人钧舌。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像涎跨,于是被迫代替她去往敵國和親洼冻。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

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