码迷,mamicode.com
首页 > 其他好文 > 详细

UI进阶 数据加密

时间:2016-05-25 00:04:36      阅读:276      评论:0      收藏:0      [点我收藏+]

标签:

一、数据安全

在互联网发展趋势迅猛的今天,数据安全的重要性日趋凸显。也成为我们必须了解的互联网知识。
在移动互联网浪潮下,用户的资金安全、企业的信息安全都是我们实际开发中必须考虑的内容。

技术分享

  • 相关术语:
    • 密钥:密钥是一种参数,它是在明文转换为密文或将密文转换为明文的算法中输入的参数。密钥分为对称密钥与非对称密钥(也可以根据用途来分为加密密钥和解密密钥)
    • 明文:没有进行加密,能够直接代表原文含义的信息
    • 密文:经过加密处理处理之后,隐藏原文含义的信息
    • 加密:将明文转换成密文的实施过程
    • 解密:将密文转换成明文的实施过程
  • 数据安全
    • 数据安全:是一种主动的包含措施,数据本身的安全必须基于可靠的加密算法与安全体系,主要是有对称算法与公开密钥密码体系两种(非对称算法),都包含了数据的加密和解密过程
    • 对称算法:对称密码算法有时又叫传统密码算法,是指加密密钥可以从解密密钥中推算出来,反过来也成立。
    • 非对称算法:指加密和解密使用不同密钥的加密算法,也称为公私钥加密。
    • 加密算法有很多种,在iOS开发当中,MD5是我们常用的摘要算法。

二、MD5

  • 哈希算法
    • 哈希算法:哈希算法将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。
    • 哈希值是一段数据唯一且极其紧凑的数值表示形式。数据的哈希值可以检验数据的完整性。一般用于快速查找和加密算法。
    • 典型的的哈希算法有:MD2、MD4、MD5 和 SHA-1等
  • MD5只能加密,无法解密
    • MD5:Message Digest Algorithm MD5(中文名为消息摘要算法第五版)为计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。
    • MD5算法具有以下特点:
      1、压缩性:任意长度的数据,算出的MD5值长度都是固定的(32位的16进制,128位的二进制)。
      2、容易计算:从原数据计算出MD5值很容易。
      3、抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。
      4、强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。

获取字符串的MD5值

1、需要引入CommonCrypto/CommonCrypto.h

2、获取字符串的MD5值

 1 #pragma mark - MD5加密字符串,不能解密
 2     // 1、准备一个字符串用于加密
 3     // 同一个字符串进行MD5加密之后得到的内容相同
 4     NSString *str = @"I Love You";
 5     // 2、因为MD5是基于C语言封装起来的,所以需要将字符串进行编码
 6     const char *data = [str UTF8String];
 7     // 3、使用字符数组去存取加密后的相关内容
 8     // CC_MD5_DIGEST_LENGTH表示长度
 9     // 因为是32位的,所以用unsigned,无符号的
10     unsigned char result[CC_MD5_DIGEST_LENGTH];
11     // 4、进行MD5加密
12     // 参数1:需要加密的内容
13     // 参数2:要加密的内容的长度
14     // 参数3:存放加密后结果的地址
15     CC_MD5(data, (CC_LONG)strlen(data), result);
16     // 5、保存结果 -- 创建可变字符串,将result数组中的内容保存到字符串中
17     NSMutableString *resultStr = [NSMutableString string];
18     // 6、遍历结果数组
19     for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
20         // 16进制的占位符%x
21         [resultStr appendFormat:@"%02x", result[i]];
22     }
23     NSLog(@"%@", resultStr);

 

MD5加密结果

技术分享

获取其它对象MD5值

1、引入<CommonCrypto/CommonCrypto.h>
2、将其它对象转化为NSData对象(可以将对象事先写入文件)
3、读取NSData对象的MD5值

 1     // 需求:创建一个数组,数组中存储元素,将这个数组写入到沙盒里
 2     // 1、创建数组
 3     NSArray *array = @[@"baby", @"yyp", @"bbh"];
 4     // 2、找Documents路径
 5     NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
 6     NSString *arrayPath = [documentPath stringByAppendingPathComponent:@"array.plist"];
 7     [array writeToFile:arrayPath atomically:YES];
 8     
 9     // 从沙盒中取出NSData类型的数据
10     NSData *data = [NSData dataWithContentsOfFile:arrayPath];
11     
12 #pragma mark - NSData类型数据加密过程
13     // 1、创建一个MD5对象
14     CC_MD5_CTX md5;
15     // 2、初始化md5
16     CC_MD5_Init(&md5);
17     // 3、准备开始进行数据的加密
18     // 参数1:MD5对象的地址
19     // 参数2:data的字节数
20     // 参数3:data的长度
21     CC_MD5_Update(&md5, data.bytes, (CC_LONG)data.length);
22     // 4、准备一个字符数组用来存储结果
23     unsigned char result[CC_MD5_DIGEST_LENGTH];
24     // 5、保存结果 -- 创建可变字符串,将result数组中的内容保存到字符串中
25     NSMutableString *resultStr = [NSMutableString string];
26     // 6、结束加密
27     CC_MD5_Final(result, &md5);
28     // 7、遍历结果数组
29     for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
30         [resultStr appendFormat:@"%02x", result[i]];
31     }
32     NSLog(@"resultStr = %@", resultStr);

MD5加密结果

技术分享

复杂类型的数据MD5加密 -- Person类加密

1、引入<CommonCrypto/CommonCrypto.h>
2、将其它对象转化为NSData对象(归档)
3、读取NSData对象的MD5值

Person.h

 1 #import <Foundation/Foundation.h>
 2 
 3 // 遵守NSCoding协议
 4 @interface Person : NSObject<NSCoding>
 5 @property (nonatomic, copy) NSString *name;
 6 @property (nonatomic, copy) NSString *gender;
 7 @property (nonatomic, assign) NSInteger age;
 8 
 9 // 自定义初始化方法
10 - (instancetype)initWithName:(NSString *)name
11                       gender:(NSString *)gender
12                          age:(NSInteger)age;
13 @end

 Person.m

 1 #import "Person.h"
 2 
 3 @implementation Person
 4 
 5 // 自定义初始化方法
 6 - (instancetype)initWithName:(NSString *)name
 7                       gender:(NSString *)gender
 8                          age:(NSInteger)age {
 9     if (self = [super init]) {
10         self.name = name;
11         self.gender = gender;
12         self.age = age;
13     }
14     return self;
15 }
16 
17 // 归档
18 - (void)encodeWithCoder:(NSCoder *)aCoder {
19     [aCoder encodeObject:self.name forKey:@"name"];
20     [aCoder encodeObject:self.gender forKey:@"gender"];
21     [aCoder encodeInteger:self.age forKey:@"age"];
22 }
23 
24 // 反归档
25 - (instancetype)initWithCoder:(NSCoder *)aDecoder {
26     self = [super init];
27     if (self) {
28         self.name = [aDecoder decodeObjectForKey:@"name"];
29         self.gender = [aDecoder decodeObjectForKey:@"gender"];
30         self.age = [aDecoder decodeIntegerForKey:@"age"];
31     }
32     return self;
33 }
34 
35 @end

ViewController.m

 1 #import "ViewController.h"
 2 #import "Person.h"
 3 #import <CommonCrypto/CommonCrypto.h>
 4 
 5 @interface ViewController ()
 6 
 7 @end
 8 
 9 @implementation ViewController
10 
11 - (void)viewDidLoad {
12     [super viewDidLoad];
13     /**
14      *  完成自定义Person对象的加密过程
15      */
16     // 创建Person类对象
17     Person *person = [[Person alloc] initWithName:@"yyp" gender:@"girl" age:23];
18     // 归档成NSMutableData类型的数据
19     NSMutableData *data = [NSMutableData data];
20     NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
21     [archiver encodeObject:person forKey:@"person"];
22     [archiver finishEncoding];
23     
24     // data加密
25     CC_MD5_CTX md5;
26     CC_MD5_Init(&md5);
27     CC_MD5_Update(&md5, data.bytes, (CC_LONG)data.length);
28     unsigned char result[CC_MD5_DIGEST_LENGTH];
29     NSMutableString *resultStr = [NSMutableString string];
30     CC_MD5_Final(result, &md5);
31     for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
32         [resultStr appendFormat:@"%02x", result[i]];
33     }
34     NSLog(@"resutltStr = %@", resultStr);
35     
36 }

 

MD5加密结果

技术分享

小节:

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

三、钥匙串加密

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

技术分享      技术分享

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

使用第三方类:KeychainItemWrapper

注意:

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

设置ARC&MRC混编

技术分享

 1 #import "ViewController.h"
 2 #import "KeychainItemWrapper.h"
 3 
 4 @interface ViewController ()
 5 
 6 @end
 7 
 8 @implementation ViewController
 9 
10 - (void)viewDidLoad {
11 #pragma mark - 钥匙串加密方式
12     // 1、创建钥匙串对象,通过相同的标记创建的钥匙串中具有相同的数据,可以看做是一个对象
13     // 参数1:标识,用于识别加密的内容(回传标识符)
14     // 参数2:分组 一般为nil
15     KeychainItemWrapper *keycharinItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"myItemWrapper" accessGroup:nil];
16     // 常用于加密用户名和密码
17     // 系统提供的键值对中的两个键,非系统的键是没法加到字典中的
18     id kUserName = (__bridge id)kSecAttrAccount;
19     id kPasswordKey = (__bridge id)kSecValueData;
20     [keycharinItem setObject:@"MBboy" forKey:kUserName];
21     [keycharinItem setObject:@"123456" forKey:kPasswordKey];
22     // 从keychain中获取存储的数据
23     NSString *userName = [keycharinItem objectForKey:kUserName];
24     NSString *password = [keycharinItem objectForKey:kPasswordKey];
25     NSLog(@"username = %@, password = %@", userName, password);
26 }
27 
28 @end

运行结果

技术分享

四、公钥加密(RSA)

  • 公钥加密简介
    • 公钥加密也叫非对称加密
    • 常用算法有RSA、ElGamal、背包算法、Rabin等等,IOS中用的最多的是RSA
    • iOS 使用 RSA 加密, 只需要公钥
  • RSA基本原理
    RSA使用"秘匙对"对数据进行加密解密.在加密解密数据前,需要先生成公钥(public key)和私钥(private key).
      公钥(public key): 用于加密数据. 用于公开, 一般存放在数据提供方, 例如iOS客户端.
      私钥(private key): 用于解密数据. 必须保密, 私钥泄露会造成安全问题.
    公钥和私钥都是使用证书生成的,并非我们自定义字符串就可以。
  •  使用openssl生成密匙对
    终端命令:

    创建一个文件夹,使用"cd 文件夹路径" 到该文件夹下 例如:cd /Users/zhaoce/Desktop/公钥加密
    然后逐条执行下列代码,会在该文件夹下生成7个文件
     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.crt
    11 -
    12 - echo "create public_key.der For IOS"
    13 - openssl x509 -outform der -in rsaCert.crt -out public_key.der
    14 -
    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.crt
    17 -
    18 - echo "create rsa_public_key.pem For Java"
    19 - openssl rsa -in private_key.pem -out rsa_public_key.pem -pubout
    20 - echo "create pkcs8_private_key.pem For Java"
    21 - openssl pkcs8 -topk8 -in private_key.pem -out pkcs8_private_key.pem -nocrypt
    22 -
    23 - echo "finished."

     

    生成7个文件

技术分享

  公钥所在文件:rsa_public_key.pem

  私钥所在文件:pkcs8_private_key.pem

  然后使用终端命令:"cat 文件名"获取文件中的密钥

技术分享

  在工程中导入第三方类:RSA

  在从终端复制密钥到Xcode中时会复制上回车符,需要大家手动删除,注意不要多删

 1 #import "ViewController.h"
 2 #import "RSA/RSA.h"
 3 
 4 @interface ViewController ()
 5 
 6 @end
 7 
 8 @implementation ViewController
 9 
10 - (void)viewDidLoad {
11     [super viewDidLoad];
12     // 获取公钥私钥数据
13     // 公钥:iOS客户端使用,我们拿到公钥以后,只需要根据公钥处理数据就可以
14     NSString *publicKey = @"-----BEGIN PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9YE8sZKdQWUZRBKDeF8xxlDcoRlT5QOJcQ7AOLc3Gswjs1fVmpPvX4E/NEV2KS0f0NEeT3URsv3LmnS6v3CTvUqbk2+SabQFiq4jfTuyW5OFYVadX6vzZnKHdX35Z7LZNwfc+slFqfWdMVyLSSoq8br87v6uonM05Mk1Mf8rK4QIDAQAB-----END PUBLIC KEY-----";
15     
16     // 私钥:用于解密数据的,不能泄露,否则会造成信息不安全
17     NSString *privateKey = @"-----BEGIN PRIVATE KEY-----MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAL1gTyxkp1BZRlEEoN4XzHGUNyhGVPlA4lxDsA4tzcazCOzV9Wak+9fgT80RXYpLR/Q0R5PdRGy/cuadLq/cJO9SpuTb5JptAWKriN9O7Jbk4VhVp1fq/Nmcod1fflnstk3B9z6yUWp9Z0xXItJKirxuvzu/q6iczTkyTUx/ysrhAgMBAAECgYBqCACMZJbhf/rE5giEEWMgvNHdNPPi0xdqfWOXrMGoXRnEMU/DduCjUC6eLPjos5nH+3WQLrVfBhp5UMyRHnt2pYGm3tsU1R5ieLZhMdcsfDQBBw67f1ov6gpktQ7r2AdJerxo2QlfhvvrjayV+TpPbRB5yk9z+z5iMccwj2vTWQJBAN/Xu7SC6YFNuZcIx5rzpOJoZ/CkdcBFvBpRGa3mAiXqv2+NyJemp0JY42x/9TiAnShrDRFd9OU72NhSjA2VHrcCQQDYlQBEbr1S4KJ1Zk7CzVppf+vIWJSSg/7oc3X98yTsoOBd5XBRQ7bLvcGiUMsHvXVibmwjrvQ7YayXQKCPCMsnAkBOsYlL7LoquyiD8JI752wQLKRd9XNwJRP8LIbanAIlUmH61d2vcudaa+WIP3P2aUDW9MujT2TJMkEJy/twyvwBAkAzVsaUciegsKzx5UmANctbvL34ZL77KBzRnyT2CJ/VE6F7wHpqWQHIs/dlcX9fG1Lq/T/XCY7NUK7nv6MPpMb7AkEA3rX/1V9HHSiTQe5MYfydB7s6duIR432xykR3ZYWjGBXNWFwwuI3wNcAJqkXWzOsbcz2oIRIZiaL9H1teOGQivg==-----END PRIVATE KEY-----";
18     
19     // 创建字符串
20     NSString *testStr = @"小暖心";
21     // 创建存储公钥加密后的字符串,并使用RSA进行加密处理
22     // 参数1:需要加密的内容
23     // 参数2:公钥字符串
24     NSString *encPublicKey = [RSA encryptString:testStr publicKey:publicKey];
25     // 创建存储用私钥解密后的字符串
26     // 参数1:由JAVA后台提供
27     // 参数2:私钥字符串
28     NSString *result = @"";  // 经过加密之后需要把加密的内容传给后台,此时后台会返回一个字符串
29     NSString *encPrivateKey = [RSA decryptString:result privateKey:privateKey];
30     NSLog(@"%@", encPublicKey);
31     NSLog(@"%@", encPrivateKey);
32 }
33 
34 @end

 

  运行结果: 

 技术分享

UI进阶 数据加密

标签:

原文地址:http://www.cnblogs.com/fearlessyyp/p/5510935.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!