你的位置:首页 > 操作系统

[操作系统]iOSDay40网络之数据安全

在互联网发展趋势迅猛的今天,数据安全的重要性日趋凸显。也成为我们必须了解的互联网知识。

在移动互联网浪潮下,用户的资金安全、企业的信息安全都是我们实际开发中必须考虑的内容。


 在这里我将字符串使用MD5加密封装为NSString的类目,下载地址:https://github.com/AlonerOwl/MD5CommonCrypto

 4> 获取其他对象MD5值

  • 引入<CommonCrypto/CommonCrypto.h>

  • 将其它对象转化为NSData对象(可以将对象事先写入文件)

 1   // 1. 创建数组 2   NSArray *array = @[@"小胖", @"Rose"]; 3    4   // 2. 找沙盒路径 5   NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 6    7   // 3. 拼接路径 8   NSString *arrayPath = [documentPath stringByAppendingPathComponent:@"array.plist"]; 9   10   // 4. 写入11   [array writeToFile:arrayPath atomically:YES];12   13   // 从沙盒中取出NSData数据14   NSData *data = [NSData dataWithContentsOfFile:arrayPath];

  • 读取NSData对象的MD5值

 1 + (NSMutableString *)dataMD5:(NSData *)data 2 { 3   // 1. 创建MD5对象 4   CC_MD5_CTX md5; 5    6   // 2. 初始化MD5对象 7   CC_MD5_Init(&md5); 8    9   // 3. 准备开始数据加密10   // 参数1:md5对象11   // 参数2:要加密的data的字节长度12   // 参数3:要加密内容的长度13   CC_MD5_Update(&md5, data.bytes, (CC_LONG)data.length);14   15   // 4. 准备一个字符串数组用来存储结构16   unsigned char result[CC_MD5_DIGEST_LENGTH];17   18   // 结束加密19   CC_MD5_Final(result, &md5);20   21   // 5. 创建一个可变字符串存放加密结构22   NSMutableString *mutableString = [NSMutableString string];23   24   // 6. 遍历数组,给可变字符串赋值25   for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {26     [mutableString appendFormat:@"%02x", result[i]];27   }28   return mutableString;29 }

  在这里我将字符串使用MD5加密封装为NSString的类目,下载地址:https://github.com/AlonerOwl/MD5CommonCrypto

 

3. 钥匙串加密

 1> 钥匙串概述

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

 2> 钥匙串加密

  • 苹果 iOS 和 Mac OS X 系统自带了一套敏感信息保存方案:"钥匙串" (Keychain)。

  • 保存在钥匙串的内容相当于系统对其做了保护,在设备锁定时进行了加密处理。

  • 钥匙串中的条目称为SecItem,但它是存储在CFDictionary中的。SecItemRef类型并不存在。SecItem有五类:通用密码、互联网密码、证书、密钥和身份。在大多数情况下,我们用到的都是通用密码

  • 钥匙串的使用和字典非常的相似

  • 用原生的 Security.framework 就可以实现钥匙串的访问、读写。但是只能在真机上进行。通常我们使用KeychainItemWrapper来完成钥匙串的加密。

 3> 钥匙串的使用

  • 拷贝钥匙串类到工程中,钥匙串类下载地址:https://github.com/AlonerOwl/KeychainItemWrapper

  • 引入标准头文件

  • 生成钥匙串对象

  • 存储加密的数据

  • 获得钥匙串对象

  • 获取加密的数据

  代码:

 1   // 1.创建钥匙串对象 2   // 参数1:标识,用于识别加密的内容(回传标识符) 3   // 参数2:分组,一般为nil 4   KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"myItemWrapper" accessGroup:nil]; 5    6   // 常用于加密用户名和密码 7   // 系统提供的键值对中的两个键,非系统的键,是无法添加到字典中的 8   id kUserName = (__bridge id) kSecAttrAccount; 9   id kUserPassword = (__bridge id) kSecValueData;10   11   [keychainItem setObject:@"MBBoy" forKey:kUserName];12   [keychainItem setObject:@"123456" forKey:kUserPassword];13   14   // 从keychain中获取存储的数据15   // 用户16   NSString *userName = [keychainItem objectForKey:kUserName];17   // 密码18   NSString *userPassword = [keychainItem objectForKey:kUserPassword];19   20   NSLog(@"%@,%@", userName, userPassword);

 4> 注意

  • 引入的头文件是MRC模式的,需要进行混编

  • 获取对象的时候Identify必须一致

  • 非系统key值是无法添加到字典中的

4. 公钥加密

 1> 概述

  • 公钥加密也叫非对称加密

  • 常用算法有RSA、ElGamal、背包算法、Rabin等等,IOS中用的最多的是RSA

  • iOS 使用 RSA 加密, 只需要公钥

 2> RSA加密的基本原理

 RSA使用"秘匙对"对数据进行加密解密.在加密解密数据前,需要先生成公钥(public key)和私钥(private key).

 

  • 公钥(public key): 用于加密数据. 用于公开, 一般存放在数据提供方, 例如iOS客户端.
  • 私钥(private key): 用于解密数据. 必须保密, 私钥泄露会造成安全问题.

 3> 使用openssl生成密匙对

  Shell代码

 1 - #!/usr/bin/env bash 2 - echo "Generating RSA key pair ..." 3 - echo "1024 RSA key: private_key.pem" 4 - openssl genrsa -out private_key.pem 1024 5 - 6 - echo "create certification require file: rsaCertReq.csr" 7 - openssl req -new -key private_key.pem -out rsaCertReq.csr 8 - 9 - echo "create certification using x509: rsaCert.crt"10 - openssl x509 -req -days 3650 -in rsaCertReq.csr -signkey private_key.pem -out rsaCert.crt11 -12 - echo "create public_key.der For IOS"13 - openssl x509 -outform der -in rsaCert.crt -out public_key.der14 -15 - echo "create private_key.p12 For IOS. Please remember your password. The password will be used in iOS."16 - openssl pkcs12 -export -out private_key.p12 -inkey private_key.pem -in rsaCert.crt17 -18 - echo "create rsa_public_key.pem For Java"19 - openssl rsa -in private_key.pem -out rsa_public_key.pem -pubout20 - echo "create pkcs8_private_key.pem For Java"21 - openssl pkcs8 -topk8 -in private_key.pem -out pkcs8_private_key.pem -nocrypt22 -23 - echo "finished."

  在你所在的路径下会生成一下公钥文件:

  私钥:

  

  RSA第三方文件下载地址:https://github.com/AlonerOwl/RSAEncrypt

5. KVO

 1> 概述

  KVO:(Key-Value-Observer)键值观察者,是观察者设计模式的一种具体实现

  KVO触发机制:一个对象(观察者),监测另一对象(被观察者)的某属性是否发生变化,若被监测的属性发生的更改,会触发观察者的一个方法(方法名固定,类似代理方法)

 2> 使用步骤

  • 注册观察者(为被观察者指定观察者以及被观察属性)

 1 // KVO 键值观察,是观察者设计模式 2 @interface ViewController () 3  4 // 观察可变数组的改变情况(苹果官方文档不建议对数组进行观察) 5 @property (nonatomic, strong) NSMutableArray *array; 6  7 @end 8  9 - (void)viewDidLoad {10   [super viewDidLoad];11   // Do any additional setup after loading the view, typically from a nib.12   13   self.array = [NSMutableArray array];14   15   // 第一步:注册观察者16   // 参数1:添加的观察者对象17   // 参数2:字符串标识的key18   // 参数3:触发添加观察者对象的时候19   /*20    NSKeyValueObservingOptionNew = 0x01 key或value只要有一个更新的时候就会触发21    NSKeyValueObservingOptionOld = 0x0222    NSKeyValueObservingOptionInitial = 0x0423    NSKeyValueObservingOptionPrior = 0x0824   */25   // 参数4:文本内容 一般为nil26   [self addObserver:self forKeyPath:@"array" options:NSKeyValueObservingOptionNew context:nil];27 }

  • 
实现回调方法

 1 // 第二步:实现回调 2 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context 3 { 4    5   NSLog(@"keyPath = %@", keyPath); 6   NSLog(@"object = %@", object); 7   NSLog(@"change = %@", change); 8    9   // 可以进行刷新UI的操作10 }

  • 
触发回调方法(被观察属性发生更改)

 1 // 第二步:实现回调 2 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context 3 { 4    5   NSLog(@"keyPath = %@", keyPath); 6   NSLog(@"object = %@", object); 7   NSLog(@"change = %@", change); 8    9   // 可以进行刷新UI的操作10 }

  • 移除观察者

  在不需要观察者的时候需要把它删除,本人就只在视图将要消失时移除

1 // 视图将要消失的时候2 - (void)viewWillDisappear:(BOOL)animated3 {4   // 在不需要观察者的时候需要把它删除5   [self removeObserver:self forKeyPath:@"array"];6 }