华山论剑之iOS加密

现在什么类型的应用程序最火? 大多数的人会说店铺类的APP和运动健身类的APP,今天我就店铺类的APP说一下这个加密技术.首先我要说一下 很多人封闭的iOS系统很安全,iOS应用也很安全,但事实上,iOS应用没有我们想象中的安全。如同安卓应用,iOS应用也面临着被破解的威胁,存在大量盗版情况。

就是在这样的情况下,所以我们就要对我们自己的APP做一些加密技术.加密的方面主要从下面几个方面入手,

类型 简介
本地数据加密 对NSUserDefaults,sqlite存储文件数据加密,保护帐号和关键信息。
URL编码加密 对程序中出现的URL进行编码加密,防止URL被静态分析
网络传输数据加密 对客户端传输数据提供加密方案,有效防止通过网络接口的拦截获取
方法体,方法名高级混淆 对应用程序的方法名和方法体进行混淆,保证源码被逆向后无法解析代码
程序结构混排加密 对应用程序逻辑结构进行打乱混排,保证源码可读性降到最低

加密主要就是从这五个方面入手.


钥匙串加密操作

当我们的应用的用户在使用我的App的时候经常要使用到一些密码,而作为程序员的我们,则需要对这些账号和密码做一些操作,如果我们不做加密设置的话,黑客就很容易获取到我们的用户信息,造成一些不必要的损失.这时候,我们就需要做一些加密的操作了.

下面我从网上找到一个代码 根据暴露的三个接口,我们就可以做出对应的操作,这样做就比直接存入NSUserDefaults要安全的多了 ,下面是在KeyChain.h的文件中写的代码

#import <Foundation/Foundation.h>
#import <Security/Security.h>
@interface KeyChain : NSObject

+ (void)save:(NSString *)service data:(id)data;//保存一个字段  service是键 data是值
+ (id)load:(NSString *)service;//根据键加载一个值
+ (void)delete:(NSString *)service;//删除一个键值对

@end

我们需要在KeyChain.m文件中写出下面的代码

#import "KeyChain.h"

@implementation KeyChain

+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service {
    return [NSMutableDictionary dictionaryWithObjectsAndKeys:
            (id)kSecClassGenericPassword,(id)kSecClass,
            service, (id)kSecAttrService,
            service, (id)kSecAttrAccount,
            (id)kSecAttrAccessibleAfterFirstUnlock,(id)kSecAttrAccessible,
            nil];
}

+ (void)save:(NSString *)service data:(id)data {
    //Get search dictionary
    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
    //Delete old item before add new item
    SecItemDelete((CFDictionaryRef)keychainQuery);
    //Add new object to search dictionary(Attention:the data format)
    [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData];
    //Add item to keychain with the search dictionary
    SecItemAdd((CFDictionaryRef)keychainQuery, NULL);
}

+ (id)load:(NSString *)service {
    id ret = nil;
    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
    //Configure the search setting
    //Since in our simple case we are expecting only a single attribute to be returned (the password) we can set the attribute kSecReturnData to kCFBooleanTrue
    [keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
    [keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
    CFDataRef keyData = NULL;
    if (SecItemCopyMatching((CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
        @try {
            ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData];
        } @catch (NSException *e) {
//            NSLog(@"Unarchive of %@ failed: %@", service, e);
        } @finally {
        }
    }
    if (keyData)
        CFRelease(keyData);
    return ret;
}

+ (void)delete:(NSString *)service {
    NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
    SecItemDelete((CFDictionaryRef)keychainQuery);
}


@end

然后我们就可以直接调用我们所暴露的接口做一些操作


MD5加密技术

对于MD5加密技术,iOS已经封装好了一些算法,我们直接调用这些算法就可,当然了,其实现在的开发人员已经不直接使用MD5加密技术,而是在上面直接加一下辅料~,让密码更难破解, 我们先看一下简单的MD5字符串加载吧.

首先,我们需要导入MD5所在的库

#import <CommonCrypto/CommonDigest.h> // Need to import for CC_MD5 access

下面,我们就对MD5的加密方法实现以下,

- (NSString *)md5:(NSString *)str
{
    const char *cStr = [str UTF8String];
    unsigned char result[16];
    CC_MD5(cStr, strlen(cStr), result); // This is the md5 call
    return [NSString stringWithFormat:
            @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
            result[0], result[1], result[2], result[3],
            result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11],
            result[12], result[13], result[14], result[15]
            ]; 
}

下面是我做的一个小的范例

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSString *str = [self md5:@"123456"];//直接调用MD5加密,返回一个字符串类型的数据
    
    NSLog(@"%@",str);
    
    
    // Do any additional setup after loading the view, typically from a nib.
}
- (NSString *)md5:(NSString *)str
{
    const char *cStr = [str UTF8String];
    unsigned char result[16];
    CC_MD5(cStr, strlen(cStr), result); // This is the md5 call
    return [NSString stringWithFormat:
            @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
            result[0], result[1], result[2], result[3],
            result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11],
            result[12], result[13], result[14], result[15]
            ]; 
}

华山论剑之iOS加密

然后接下来,我们看一下各位技术大牛是如何在简单的MD5加密技术中往上加上辅料的…

#import "ViewController.h"


#import <CommonCrypto/CommonDigest.h> // Need to import for CC_MD5 access

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //假设现在我们需要登录功能,那么我们在请求数据的时候,就需要对我们的密码进行一些简单的处理,比如加上时间戳,或者一些字符串字段
    NSString *userName = @"dongGe";//账号
    NSString *userKey = @"123456";//密码
    NSString *troken = @"5355";//要添加的字段(可以是时间戳)
    
    
    NSString *newKey = [userKey stringByAppendingString:troken];
    
    newKey = [self md5:newKey];//进行MD5加密
    
    //然后就是请求我们的网络数据
    NSString *urlString = [NSString stringWithFormat:@"http://localhost/login.php"];
    
    NSURL *url = [NSURL URLWithString:urlString];
    
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    
    [request setHTTPMethod:@"POST"];//设置请求方式为POST请求方式
    
    NSString *body = [NSString stringWithFormat:@"username=%@&password=%@",userName , userKey];
    
    request.HTTPBody = [body dataUsingEncoding:NSUTF8StringEncoding];//设置请求参数
    
    NSURLSessionDataTask *dataTask = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        
        if (!error && data != nil) {
            
            NSLog(@"请求成功");
        }else{
        
            NSLog(@"请求失败!");
        
        }
        
        
    }];
    
    [dataTask resume];
    
    
    
}
- (NSString *)md5:(NSString *)str
{
    const char *cStr = [str UTF8String];
    unsigned char result[16];
    CC_MD5(cStr, strlen(cStr), result); // This is the md5 call
    return [NSString stringWithFormat:
            @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
            result[0], result[1], result[2], result[3],
            result[4], result[5], result[6], result[7],
            result[8], result[9], result[10], result[11],
            result[12], result[13], result[14], result[15]
            ]; 
}




- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

当然了,上面的只是我们简单加的辅料,我们可以让这些辅料更加完美一些.那就是加上公钥和私钥还有时间戳,这样的话,我们可以更好让我们的密码不容易破解.

今天就说到这,后期我将带给大家更多的技术分享,喜欢的话,就点个喜欢吧,谢谢各位看官了~.
本文参考博客
如果你觉得生活不如意,没有关系,那只是生活在考验你,加油!
上一篇:redis--10--geospatial地理位置详解 hyperloglog基数统计 bitmap位图场景详解


下一篇:【Redis】特殊数据类型 - HyperLogLog (基数统计)