首先我們來看項目需求:
這是一款脫機門禁的設(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了 感興趣的可以加群找他)