华山论剑之iOS加密

作者: 神经骚栋 | 来源:发表于2016-02-27 11:17 被阅读511次

    现在什么类型的应用程序最火? 大多数的人会说店铺类的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]
                ]; 
    }
    
    
    打印结果

    然后接下来,我们看一下各位技术大牛是如何在简单的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
    
    

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

    今天就说到这,后期我将带给大家更多的技术分享,喜欢的话,就点个喜欢吧,谢谢各位看官了~.

    本文参考博客http://blog.csdn.net/xn4545945

    如果你觉得生活不如意,没有关系,那只是生活在考验你,加油!

    相关文章

      网友评论

      本文标题:华山论剑之iOS加密

      本文链接:https://www.haomeiwen.com/subject/kljwkttx.html