标签:
本文主要介绍下现阶段以iOS客户端安全应用及iOS9系统可能需要考虑的一些安全策略
1、指纹识别
iOS 8 SDK向开发者公开了Touch ID指纹识别功能,允许App对用户身份进行本地验证。
使用Touch ID非常简单,只需要2步即可:
1) 检查Touch ID是否可用。
2)获得指纹验证结果。
// 引入LocalAuthentication框架
#import <LocalAuthentication/LocalAuthentication.h>
/// 指纹识别的演示
- (void)laDemo {
// 0. 版本检测,判断用户手机是否是 iOS 8.0 以上版本
if ([UIDevice currentDevice].systemVersion.floatValue < 8.0) {
NSLog(@"系统版本太低");
return;
}
NSLog(@"%@", [UIDevice currentDevice].systemVersion);
// 1. 实例化本地身份验证上下文
LAContext *ctx = [[LAContext alloc] init];
// 2. 判断是否支持指纹识别
if (![ctx canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:NULL]) {
NSLog(@"不支持指纹识别");
return;
}
// 3. 指纹输入 -- 异步的输入
[ctx evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:@"输入指纹登录" reply:^(BOOL success, NSError *error) {
// 回调执行的线程是后台线程,如果要更新UI,需要注意线程间通讯!
NSLog(@"%d %@ %@", success, error, [NSThread currentThread]);
// 如果成功,表示手机主人按照提示的文字确认并且输入了指纹
if (success) {
// 代码实现中,具体的操作,不会受到影响
// 直接登录
[self postLogin];
}
}];
// 判断是否异步!
NSLog(@"come here");
}
2、钥匙串介绍
1) 苹果的“生态圈”,钥匙串访问,使用AES256加密算法,能够保证用户密码的安全,
2) 钥匙串访问SDK,是苹果iOS7.0.3版本后公布的
3) 钥匙串访问的接口是纯c语言的,但是网络的有一个哥们把它封装成OC了使用箱单简单
4) 钥匙串访问的密码保存在哪里?只要苹果知道
5) 钥匙串访问的第三方框架,是对C框架的封装
6)第三方框架应用
代码示例:
// MARK: - 保存用户信息
#define GZUserNameKey @"GZUserNameKey"
#define GZUserPwdKey @"GZUserPwdKey"
- (void)saveUserInfo {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:self.usernameText.text forKey:GZUserNameKey];
// 同步
[defaults synchronize];
// 将密码保存到钥匙串访问
/**
参数:
1. 密码(明文)- 钥匙串访问本身使用的 AES 256 的加密,就是安全的,使用的时候,直接传递密码明文即可
2. 服务名-可以随便写
建议使用 bundleId - 应用程序的唯一标示,每一个上架的应用程序,都有一个唯一的 bundleId
使用第三方的 SDK,内购,远程推送...
3. 账户名(用户名)
钥匙串的密码到底保存在哪里 - 只有苹果知道!
关于 SSKeyChain 的框架,是对底层 C 语言的封装,不用去看!只要会用,知道概念就好!
如果没有钥匙串的访问,本地密码的保存会相当麻烦,需要使用 RSA(密钥) & AES(加密&解密的)
*/
NSString *bundleId = [NSBundle mainBundle].bundleIdentifier;
NSLog(@"%@", bundleId);
[SSKeychain setPassword:self.pwdText.text forService:bundleId account:self.usernameText.text];
}
*读取信息
// MARK: - 加载用户信息
- (void)loadUserInfo {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
self.usernameText.text = [defaults objectForKey:HMUserNameKey];
// 从钥匙串来加载用户信息,只有自己开发的应用程序,才能够互相看到账号
NSLog(@"%@", [SSKeychain allAccounts]);
NSString *bundleId = [NSBundle mainBundle].bundleIdentifier;
// 如果钥匙串中没有保存对应信息,返回的是空字符串
self.pwdText.text = [SSKeychain passwordForService:bundleId account:self.usernameText.text];
}
3、BASE64 介绍
从iOS7.0开始,苹果提供了base64的编码解码的支持,
1) 特点:
*原本的8bit一组,改为 每6bit一组,不足的补0,每两个0用一个“=” 表示,
* 用base64编码之后,结果会变大约1/3
2)二进制位数是6的倍数时
3)二进制位数不是6的倍数时,向后补0
终端base64编码:echo -n ”A“ | base64 —> QQ==
反算:echo -n ”QQ==“ | base64 -D —> A
终端:echo -n ”BC“ | base64 —> QkM=
反算:echo -n ”QkM=“ | base64 -D —> BC
4)文件应用
* base64 123.png -o 123.txt // 编码16进制文本
* base64 123.txt -o 321.png -D // 反解密16进制二进制数据
5)编码实现
// MARK: - base64 编码 & 解码
// 从 iOS 7.0 开始,苹果提供了 base64 的编码解码的支持
- (NSString *)base64Encode:(NSString *)str {
// 1. 转换成二进制
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
// 2. 转换成base64的编码结果
return [data base64EncodedStringWithOptions:0];
}
// MARK: - base 64 解码
// 参数:是 base64 编码后的字符串
- (NSString *)base64Decode:(NSString *)str {
// 1. 建立二进制数据,使用 base64 编码后的字符串实例化二进制数据
// 结果就是解码后的二进制数据
NSData *data = [[NSData alloc] initWithBase64EncodedString:str options:0];
// 2. 返回字符串
return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
4、 HASH散列函数
1)特点:
*对任意二进制数据进行散列,得到一个定长的字符串,类似“指纹”,
数据摘要, 比如:如果MD5 散列 ,总会得到一个32位字符,
* 不可逆
2)常用函数
*MD5,目前国内用得非常之多,被清华大学的王小云通过“碰撞算法破解”
*SHA1:也被破解
* SHA256
*SHA512
3)MD5用用户安全登录时的安全问题
方案1:早期的方案,加盐,必须够复杂,
方案2:HMAC,是一个结合了散列函数的加密算法,
*具体是给定一个“密钥”,分别作两次加密和散列,密钥的抢夺不那么高,
* 国外用得比较多
* 实现
NSString *key = @"test".md5String;
[pwd hmacMD5StringWithKey:key];
方案3:
* 用户密码有一个要求,相同的加密算法+相同的密码明文,每次的结果是不一样的
* 只要每次不一样,黑客才不好猜
* 用户注册安全:关于用户第一次的密码安全,被黑客拦截的几率非常低的
通常有这些辅助安全手段,比如,IP辅助、手机绑定
* 客户端代码
/// 利用时间,生成密码
- (NSString *)timePassword:(NSString *)pwd {
// 1. key 密钥
NSString *key = @"test".md5String;
NSLog(@"key - %@", key);
// 2. pwd + hmac
pwd = [pwd hmacMD5StringWithKey:key];
// 3. 取当前的系统时间
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
fmt.dateFormat = @"yyyy-MM-ddHH:mm";
NSString *dateStr = [fmt stringFromDate:[NSDate date]];
NSLog(@"当前系统时间字符串 %@", dateStr);
pwd = [pwd stringByAppendingString:dateStr];
// 再次 hmac
return [pwd hmacMD5StringWithKey:key];
}
5、 对称加密算法
1) 对称加密算法——传统加密算法
* 加密和解密使用同一个“密钥”
* 密钥会定期更换,密钥管理很重要
* 可逆
2)对称经典算法
—DES 数据解密标准(用的少,因为强度不够)
—3DES 使用三个密钥,对相同的数据执行三次加密
—AES 高级加密标准,目前是美国国家安全局使用,
苹果的钥匙串访问就是使用AES加密的
3)ECB 电子密码本,
原理:将大的数据块,拆分成若干小的数据块,就是说每个块都是独立加密的
应用: cd Destop
mkdir 加密
cd 加密
vim abc.txt
加密: openssl enc -des-ecb -K 616263 -nosalt -in abc.txt -out msg.bin
解密: openssl enc -des-ecb -K 616263 -nosalt -in msg.bin -out msg.txt -d
打开文件 :xxd msg.bin
4)CBC 密码块链,
原理:将大的数据块,拆分成若干小的数据块,依次加密,且每一块加密和
和前一个加密块相关联,增加破译难度
加密: openssl enc -des-cbc -K 616263 -iv 0102030405060708 -nosalt -in abc.txt -out msg1.bin
解密:openssl enc -des-cbc -K 616263 -iv 0102030405060708 -nosalt -in msg1.bin -out msg2.txt -d
打开文件 :xxd msg.bin
5) iv 初始向量
现在密码学的加密很多算法都在圆、椭圆、球上做文章,
6)代码演练
// AES - ECB 加密
NSString *key = @"test";
NSLog(@"加密 %@", [[EncryptionTools sharedEncryptionTools] encryptString:@"hello" keyString:key iv:nil]);
NSLog(@"解密 %@", [[EncryptionTools sharedEncryptionTools] decryptString:@"KNhIRJWjZxUtgzDDlpggMg==" keyString:key iv:nil]);
// AES - CBC 加密
// *** 一定记住 iv 在程序中定义的方式!
uint8_t iv[8] = {1, 2, 3, 4, 5, 6, 7, 8};
NSData *ivData = [NSData dataWithBytes:iv length:sizeof(iv)];
NSLog(@"加密 %@", [[EncryptionTools sharedEncryptionTools] encryptString:@"hello" keyString:key iv:ivData]);
NSLog(@"解密 %@", [[EncryptionTools sharedEncryptionTools] decryptString:@"gap7hnMbdynogDKpJVaTOw==" keyString:key iv:ivData]);
// DES - ECB 加密
[EncryptionTools sharedEncryptionTools].algorithm = kCCAlgorithmDES;
NSLog(@"DES 加密 %@", [[EncryptionTools sharedEncryptionTools] encryptString:@"hello" keyString:key iv:nil]);
NSLog(@"解密 %@", [[EncryptionTools sharedEncryptionTools] decryptString:@"lfaJnK1OAsc=" keyString:key iv:nil]);
打印结果:
2015-08-28 20:52:02.293 08-对称加密算法[21804:161889] 加密 KNhIRJWjZxUtgzDDlpggMg==
2015-08-28 20:52:02.294 08-对称加密算法[21804:161889] 解密 hello
2015-08-28 20:52:02.294 08-对称加密算法[21804:161889] 加密 gap7hnMbdynogDKpJVaTOw==
2015-08-28 20:52:02.294 08-对称加密算法[21804:161889] 解密 hello
2015-08-28 20:52:02.294 08-对称加密算法[21804:161889] DES 加密 lfaJnK1OAsc=
2015-08-28 20:52:02.295 08-对称加密算法[21804:161889] 解密 hello
终端命令:
* DES(ECB)加密
$ echo -n hello | openssl enc -des-ecb -K 616263 -nosalt | base64
* DES(CBC)加密
$ echo -n hello | openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt | base64
* AES(ECB)加密
$ echo -n hello | openssl enc -aes-128-ecb -K 616263 -nosalt | base64
* AES(CBC)加密
$ echo -n hello | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt | base64
* DES(ECB)解密
$ echo -n HQr0Oij2kbo= | base64 -D | openssl enc -des-ecb -K 616263 -nosalt -d
* DES(CBC)解密
$ echo -n alvrvb3Gz88= | base64 -D | openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt -d
* AES(ECB)解密
$ echo -n d1QG4T2tivoi0Kiu3NEmZQ== | base64 -D | openssl enc -aes-128-ecb -K 616263 -nosalt -d
* AES(CBC)解密
$ echo -n u3W/N816uzFpcg6pZ+kbdg== | base64 -D | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt -d
* 提示:
* 1> 加密过程是先加密,再base64编码
* 2> 解密过程是先base64解码,再解密
*/
7) 对称加密:终端测试指令
* DES(ECB)加密
* $ echo -n hello | openssl enc -des-ecb -K 616263 -nosalt | base64
*
* DES(CBC)加密
* $ echo -n hello | openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt | base64
*
* AES(ECB)加密
* $ echo -n hello | openssl enc -aes-128-ecb -K 616263 -nosalt | base64
*
* AES(CBC)加密
* $ echo -n hello | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt | base64
*
* DES(ECB)解密
* $ echo -n HQr0Oij2kbo= | base64 -D | openssl enc -des-ecb -K 616263 -nosalt -d
*
* DES(CBC)解密
* $ echo -n alvrvb3Gz88= | base64 -D | openssl enc -des-cbc -iv 0102030405060708 -K 616263 -nosalt -d
*
* AES(ECB)解密
* $ echo -n d1QG4T2tivoi0Kiu3NEmZQ== | base64 -D | openssl enc -aes-128-ecb -K 616263 -nosalt -d
*
* AES(CBC)解密
* $ echo -n u3W/N816uzFpcg6pZ+kbdg== | base64 -D | openssl enc -aes-128-cbc -iv 0102030405060708 -K 616263 -nosalt -d
*
* 提示:
* 1> 加密过程是先加密,再base64编码
* 2> 解密过程是先base64解码,再解密
*/
6、非对称加密算法(RSA)--现代加密算法
1)非对称加密需要两个密钥:公钥和私钥
* 公钥加密,私钥解密
* 私钥加密,公钥解密
2)特点
* 算法强度复杂、安全性依赖于算法与密钥
* 加密解密速度慢
所以实际应用中,应用对称加密算法加密大的数据,用非对称加密算法对对称算法的密钥进行加密。
3)RSA算法原理
1> 找出两个“很大”的质数:P & Q
* N = P * Q
* M = (P-1) *(Q-1)
2> 找出整数E,E与M互质,既除了1之外,没有其他的公约数
3> 找出整数D,使得ED除以M于1,既(ED)%M = 1
4> 经过上述准备工作之后,可以得到:
* E是公钥,负责加密
* D是私钥,负责加密
* N负责公钥和私钥之间的联系
5> 加密算法,假定对X进行加密
* (X ^E)% N = Y
6> 解密算法,根据费尔马小小定义,可以使用以下公式解密
* (Y ^ D)% N = X
代码演练
// 1. 加载公钥
[[RSACryptor sharedRSACryptor] loadPublicKey:[[NSBundle mainBundle] pathForResource:@"rsacert.der" ofType:nil]];
// 2. 加载私钥 - 密码就是生成p12的时候指定的密码
[[RSACryptor sharedRSACryptor] loadPrivateKey:[[NSBundle mainBundle] pathForResource:@"p.p12" ofType:nil] password:@"123456"];
实际应用中可选择:openssl框架
7、程序开发证书生成指令
// 打开终端:输入以下命令生成私钥
openssl genrsa -out private.pem 1024
// 创建证书请求 包含公钥、组织信息、联系信息
openssl req -new -key private.pem -out rsacert.csr
// 生成证书并签名,有效期10年 这里面文件内容为base64文件
openssl x509 -req -days 3650 -in rsacert.csr -signkey private.pem -out rsacert.crt
// 转换格式-rsacert.crt格式文件转换成DER格式 实际是base64解码成二进制文件
openssl x509 -outform der -in rsacert.crt -out rsacert.der
// 导出P12文件
openssl pkcs12 -export -out p.p12 -inkey private.pem -in rsacert.crt
标签:
原文地址:http://www.cnblogs.com/guozhong/p/4809000.html