iOS进阶学习-网络之数据安全

一、数据安全

  

  1、术语:

  • 密钥:密钥是一种参数,它是在明文转换为密文或将密文转换为明文的算法中输入的参数。密钥分为对称密钥与非对称密钥(也可以根据用途来分为加密密钥和解密密钥)。
  • 明文:没有进行加密,能够直接代表原文含义的信息。
  • 密文:经过加密处理处理之后,隐藏原文含义的信息。
  • 加密:将明文转换成密文的实施过程。
  • 解密:将密文转换成明文的实施过程。

  2、数据安全

  • 数据安全:是一种主动的包含措施,数据本身的安全必须基于可靠的加密算法与安全体系,主要是有对称算法与公开密钥密码体系两种(非对称算法),都包含了数据的加密和解密过程
  • 对称算法:对称密码算法有时又叫传统密码算法,是指加密密钥可以从解密密钥中推算出来,反过来也成立。
  • 非对称算法:非对称密钥也叫公开密钥加密,就是不能由其中一个密钥推导出另一个密钥。
  • 加密算法有很多种,在iOS开发当中,MD5是我们常用的摘要算法。

二、MD5加密

  1、哈希算法:

  • 哈希算法:哈希算法将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。
  • 哈希值是一段数据唯一且极其紧凑的数值表示形式。数据的哈希值可以检验数据的完整性。一般用于快速查找和加密算法。
  • 典型的的哈希算法有:MD2、MD4、MD5 和 SHA-1等。

  2、MD5:

  • MD5:Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。
  • MD5算法具有以下特点:
  • 压缩性:任意长度的数据,算出的MD5值长度都是固定的(16进制,32位)。
  • 容易计算:从原数据计算出MD5值很容易。
  • 抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
  • 强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。

  3、获取字符串MD5值:引入<CommonCrypto/CommonCrypto.h>、获取字符串的MD5值。

  代码示例:

复制代码
    // 1.准备一个字符串用于加密(同一个字符串进行MD5加密出来的内容类似)
    NSString *str = @"I Love you";
    // 2.因为MD5是基于C语言的,所以需要将字符串进行编码
    const char *data = [str UTF8String];
    // 3.使用字符串数组去存取加密后相关的内容(MD5 16进制,32位)
    // CC_MD5_DIGEST_LENGTH 表示长度
    unsigned char result [CC_MD5_DIGEST_LENGTH];
    // 4.进行MD5加密
    // 参数1:需要加密的内容
    // 参数2:要加密的data的一个长度
    // 参数3:存储加密结果的数组(MD5)
    CC_MD5(data, (CC_LONG)strlen(data), result);
    // 5.创建可变字符串,保存结果
    NSMutableString *mStr = [NSMutableString string];
    // 6.遍历结果数组,然后添加到可变字符串中
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        [mStr appendFormat:@"%02x", result[i]];
    }
复制代码

  4、获取其它对象MD5值:引入<CommonCrypto/CommonCrypto.h>、将其它对象转化为NSData对象(可以将对象事先写入文件)、读取NSData对象的MD5值。
  代码示例:(以数组为例)

复制代码
  // 需求:创建一个数组,数组中存储元素,将这个数组写入到沙盒里
    // 创建数组
    NSArray *array = @[@"Jack", @"Rose"];
  // 找沙盒路径
    NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    // 拼接路径
    NSString *arrayPath = [path stringByAppendingPathComponent:@"array.plist"];
    // 写入
    [sender writeToFile:arrayPath atomically:YES];
    
    // 从沙盒中取出NSData数据
    NSData *data = [NSData dataWithContentsOfFile:arrayPath];
   
    
    // NSData类型数据加密过程
    // 1.创建MD5对象
    CC_MD5_CTX md5;
    
    // 2.初始化MD5对象
    CC_MD5_Init(&md5);
    
    // 3.准备开始进行数据加密
    CC_MD5_Update(&md5, data.bytes, (CC_LONG)data.length);
    
    // 4.结束MD5加密
    // 准备一个字符串数组用来存储结果
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    CC_MD5_Final(result, &md5);
    // 5.获取结果
    NSMutableString *mStr = [[NSMutableString alloc] initWithCapacity:CC_MD5_DIGEST_LENGTH];
    // 遍历数组给可变字符串赋值
    for (int i = 0; i< CC_MD5_DIGEST_LENGTH; i++) {
        [mStr appendFormat:@"%02x", result[i]];
    }
  NSLog(@"%@", mStr);
复制代码

  注:

  • 哈希算法是一种摘要算法,主要作用是用来获取数据的摘要。严格意义上来说不属于加密算法(因为没有解密过程)
  • 获取字符串的MD5值比较简单,其它对象可以先转化成NSData对象再进行操作
  • 可以根据路径直接获取文件数据,也可以将对象写入文件件后获取为NSData对象
  • iOS同样支持SHA1、base64、AES、钥匙串等方式加密数据

三、钥匙串加密

  1、钥匙串简介:钥匙串:(英文:Keychain)是苹果公司Mac OS中的密码管理系统。它在Mac OS 8.6中和iOS7之后被导入,并且包括在了所有后续的各版本中。一个钥匙串可以包含多种类型的数据:密码(包括网站,FTP服务器,SSH帐户,网络共享,无线网络,群组软件,加密磁盘镜像等),私钥,电子证书和加密笔记等。

  2、钥匙串加密:

  • 苹果 iOS 和 Mac OS X 系统自带了一套敏感信息保存方案:"钥匙串" (Keychain)。
  • 保存在钥匙串的内容相当于系统对其做了保护,在设备锁定时进行了加密处理。
  • 钥匙串中的条目称为SecItem,但它是存储在CFDictionary中的。SecItemRef类型并不存在。SecItem有五类:通用密码互联网密码、证书、密钥和身份。在大多数情况下,我们用到的都是通用密码。
  • 钥匙串的使用和字典非常的相似。
  • 用原生的 Security.framework 就可以实现钥匙串的访问、读写。但是只能在真机上进行。通常我们使用KeychainItemWrapper(github下载地址)来完成钥匙串的加密。

  3、钥匙串的使用:

  • 拷贝钥匙串类到工程中
  • 引入标准头文件
  • 生成钥匙串对象
  • 存储加密的数据
  • 获得钥匙串对象
  • 获取加密的数据
  • 代码示例:
复制代码
    // 首先需要导入钥匙串的第三方KeychainItemWrapper.h/m
    // 创建钥匙串对象
    // 参数1:标识,用于识别后面加密的内容(回传标识符)
    // 参数2:分组,一般为nil
    KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:identifier accessGroup:nil];
    // 常用与加密用户名和密码
    // 系统提供的键值对中的两个键,非系统的键是没法添加到字典中的
    id kUserName = (__bridge id)kSecAttrAccount;
    id kPasswordName = (__bridge id)kSecValueData;
    [keychainItem setObject:@"user" forKey:kUserName];
    [keychainItem setObject:@"123456" forKey:kPasswordName];
    // 通过相同的标识创建的钥匙串中具有相同的数据
    KeychainItemWrapper *keychainItem2 = [[KeychainItemWrapper alloc] initWithIdentifier:identifier accessGroup:nil];
    NSString *name = [keychainItem objectForKey:kUserName];
    NSString *pwd = [keychainItem2 objectForKey:kPasswordName];
    NSLog(@"%@, pwd = %@", name, pwd);
复制代码

  4、注意:

  • 引入的头文件是MRC模式的,需要进行混编
  • 获取对象的时候Identify必须一致
  • 非系统key值是无法添加到字典中的

四、公钥加密

  1、公钥加密简介:

  • 公钥加密也叫非对称加密。
  • 常用算法有RSA、ElGamal、背包算法、Rabin等等,IOS中用的最多的是RSA(github下载地址)。
  • iOS 使用 RSA 加密, 只需要公钥。
  • 首先需要引入第三方RSA.h。

  2、公钥加密:(公钥和私钥的具体生成方法)

复制代码
//公钥和私钥都是使用证书生成的,并非我们自定义字符串就可以。我们使用的是生成好的公钥和私钥
//其中-----BEGIN PUBLIC KEY-----和-----END PUBLIC KEY-----不属于密钥部分
//公钥:iOS客户端使用,我们拿到手公钥以后,只需要根据公钥处理数据就可以
    // 获取公钥的数据
    NSString *publicKey = @"-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDfzVL2ZaZvmSGAl6j3Fxsn1aqYq1gbDhQGZIeLxDwh5FVNdIvGIFe/S3wlTIO8lHlc9IACD894GG6Aqlfs24oTgKeHGCIiaBKB7x3g458/GbwSiOryUnVxJKFkV+lKB9TlJJW4egcHieiN/m1xKnlKmRsGlTJYyoY7Nhihyc8HAQIDAQAB-----END PUBLIC KEY-----";
    // 创建字符串
    NSString *testStr = @"加密示例";
    // 创建存储公钥的字符串,加密
    NSString *encPublicKey = [RSA encryptString:testStr publicKey:publicKey];
    NSLog(@"encpublic = %@", encPublicKey);
复制代码

  3、私钥解密:(私钥解密的字符串需要由JAVA后台提供,)

复制代码
 // 私钥:用于解密数据的.注意:不能泄露,否则数据不安全!
    NSString *privateKey = @"-----BEGIN PRIVATE KEY-----MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAN/NUvZlpm+ZIYCX  qPcXGyfVqpirWBsOFAZkh4vEPCHkVU10i8YgV79LfCVMg7yUeVz0gAIPz3gYboCqV+zbihOAp4cYIiJoEoHvHeDjnz8ZvBKI6vJSdXEkoWRX6UoH1OUklbh6BweJ6I3+bXEqeUqZGwaVMljKhjs2GKHJzwcBAgMBAAECgYEAjPJIv3kBOuNb4BqjhQn+RjYgfIncsR1Kq0QAwZtSq52bw24U4TBZUtZ9Vxg7FzcCv/IT9Dh01xO79DhTq44QBE7Gkxy9sLK/uKo6ffnYxWxx0/l6yWtPLiwRfzvI1BInnxf24UOn/Qe1wZPBG305y3es2mdIem5Kko7SVHqtLYECQQDzd4cxIYcOZIyVWjTCIpwC6w45yRbndBbpt4GpgOZ6    hGQ8eeFHpZjLnJgHWISnCvCG76PWBFG+4fwewL7/5mNJAkEA61Klr4wnMCUyrkjAPK+pt9yQLb71qoobendLFd1BoYL1fZNar3ntkq0bp4AB+MkwS2dZvXAJKXTtyw9fBH/N+QJBAKwXbOP5gvFVeVmIbYpb1FLrux51WU8464lAQNKDXmZzdjaZH/f4wUwK4BsxInLAdMusT+5TF0UJj6BdNaTEQKECQ+duJLt7BwM2tVzORrOfKwMgEwRYMpSSb8dFl9lNtuEkUIIqAfrxwuv5XGeMEf0BcasMfdoDSKLW3aENLjHV5kCQQC4FJK6    nB02fK7f1co1254OlaYHDmD7NErYAazqeT+KVHZjV76rO6BGeldy+SnXTzLrWGbIjxgYr1bFTXL+0AI/-----END PRIVATE KEY-----";
    // 创建存储私钥的字符串
    NSString *result = @"";// 经过加密之后需要把加密的内容传送给后台,此时后台会给你返回一个字符串
    // 参数1:由java后台提供
    // 参数2:私钥
    NSString *encPrivateKey = [RSA decryptString:result privateKey:privateKey];
    NSLog(@"(PHP enc)encPrivate = %@", encPrivateKey);
复制代码

五、KVO

  1、KVO简介:

  • KVO:(Key-Value-Observer)键值观察者,是观察者设计模式的一种具体实现。
  • KVO触发机制:一个对象(观察者),监测另一对象(被观察者)的某属性是否发生变化,若被监测的属性发生的更改,会触发观察者的一个方法(方法名固定,类似代理方法)。

  2、KVO使用步骤:

  • 注册观察者(为被观察者指定观察者以及被观察属性)
;
  • 实现回调方法
;
  • 触发回调方法(被观察属性发生更改);
  • 移除观察者。
  • 代码示例:
复制代码
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
     // 第一步:注册观察者\
        //参数1:添加的观察者对象\
        //参数2:字符串标识的key\
        //参数3:什么时候回触发添加观察者对象\
        //NSKeyValueObservingOptionNew key和value只要有一个更新的时候就会触发\
        //NSKeyValueObservingOptionOld \
        //NSKeyValueObservingOptionInitial\
        //NSKeyValueObservingOptionPrior\
        //参数4:文本内容 一般为nil
    
    [self addObserver:self forKeyPath:@"array" options:NSKeyValueObservingOptionNew context:nil];
}
// 视图将要消失的时候
- (void)viewWillDisappear:(BOOL)animated
{
    // 在不需要观察者的时候
    [self removeObserver:self forKeyPath:@"array"];
}
// 第二步:实现回调方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
{
    NSLog(@"keyPath = %@",keyPath);
    NSLog(@"object = %@", object);
    NSLog(@"change = %@", change);
    // 可以进行刷新UI的操作
    
}
// 第三步:触发可变数组进行改变
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    NSArray *subArr = @[@"1", @"2", @"3"];
    // 根据keyPath获取到可变数据对象,setArray给可变数组对象设置数据
    [[self mutableArrayValueForKeyPath:@"array"] setArray:subArr];
    NSLog(@"subArr = %@", [self mutableArrayValueForKeyPath:@"array"]);
}
复制代码

 

 
 
posted @ 2016-05-15 12:34  代码我的爱  阅读(449)  评论(0编辑  收藏  举报