iOS下 AES128加密算法获取动态密码的实现

首先我们来看项目需求:


这是一款脱机门禁的设备,后台会给我们返回机器序列号和密钥,但是后台只会给我们返回6个字节的密钥和6个字节的机器序列号,首先我们需要将6个字节的密钥补齐为16字节

//判断秘钥长度 不够32位后面补0
这里的self.OfflineKey存储的是我获取的密钥
self.OfflineKeyStr 是要加密之前补齐16字节的密钥
    if ([self.OfflineKey length] < 32) {
        NSString *str = [self.OfflineKey stringByPaddingToLength:32 withString:@"0" startingAtIndex:0];
        self.OfflineKeyStr = str;
    }

因为是动态密码,所以这里根据的是时间的变化改变密码的值
这里的self.OfflineNum存储的是我获取的机身号
self.OfflineNumStr 是要加密之前补齐16字节的时间+机身号

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;
    }

到目前为止 我们已经准备好了要加密的数据
下面准备进行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;
}


// 普通字符串转换为十六进
+ (NSString *)hexStringFromData:(NSData *)data {
    Byte *bytes = (Byte *)[data bytes];
    // 下面是Byte 转换为16进制。
    NSString *hexStr = @"";
    for(int i=0; i<[data length]; i++) {
        NSString *newHexStr = [NSString stringWithFormat:@"%x",bytes[i] & 0xff]; //16进制数
        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
//十六进制转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];
    //转为16字节
    NSData *data = [AES128Util dataForHexString:encryStr];
    //截取后三个字节
    NSData *last3data = [data subdataWithRange:NSMakeRange(data.length-3, 3)];
    //变为int整形
    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(@"动态码==%@",result);

这里拿到的动态码就是最终我们需要的动态密码,因为我们加密只到天,所以密码是一天一变.

特别感谢简书-iOS开发交流群 群号:361736344 中深圳-标哥 的帮助(这里就不泄露QQ了 感兴趣的可以加群找他)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,265评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,078评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,852评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,408评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,445评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,772评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,921评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,688评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,130评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,467评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,617评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,276评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,882评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,740评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,967评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,315评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,486评论 2 348

推荐阅读更多精彩内容