- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章iOS中常见的几种加密方法总结由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
前言 。
在我们日常开发中,加密是必不可少的一部分,而普通加密方法是讲密码进行加密后保存到用户偏好设置中,钥匙串是以明文形式保存,但是不知道存放的具体位置,下面本文将详细给大家介绍iOS中常见的几种加密方法,下面话不多说了,来一起看看详细的介绍吧.
一. base64加密 。
将文件进行加密 。
1
2
3
4
5
6
|
// 获取需要加密文件的二进制数据
NSData *data = [NSData dataWithContentsOfFile:@
"/Users/wangpengfei/Desktop/photo/IMG_5551.jpg"
];
// 或 base64EncodedStringWithOptions
NSData *base64Data = [data base64EncodedDataWithOptions:0];
// 将加密后的文件存储到桌面
[base64Data writeToFile:@
"/Users/wangpengfei/Desktop/123"
atomically:YES];
|
将文件进行解密 。
1
2
3
4
5
6
|
// 获得加密后的二进制数据
NSData *base64Data = [NSData dataWithContentsOfFile:@
"/Users/wangpengfei/Desktop/123"
];
// 解密 base64 数据
NSData *baseData = [[NSData alloc] initWithBase64EncodedData:base64Data options:0];
// 写入桌面
[baseData writeToFile:@
"/Users/wangpengfei/Desktop/IMG_5551.jpg"
atomically:YES];
|
利用终端命令进行base64运算
1
2
3
4
5
6
7
|
// 将文件 meinv.jpg 进行 base64运算之后存储为 meinv.txt
base64 meinv.jpg -o meinv.txt
// 讲meinv.txt 解码生成 meinv.png
base64 -D meinv.txt -o meinv.png
// 将字符串 "hello" 进行 base 64 编码 结果:aGVsbG8=cho "hello" | base64
// 将 base64编码之后的结果 aGVsbG8= 反编码为字符串
echo aGVsbG8= | base64 -D
|
二. POST加密 。
A. 搭建UI框架 。
B. 实现基本加密 。
抽取出读取数据的方法 。
1
2
3
4
5
6
7
8
|
- (
void
)readLocalUserInfo {
// 1. 实例化偏好设置对象
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
// 2. 取出数据进行赋值
self.userName.text = [userDefaults objectForKey:kUserNameKey];
// 此时读取的是加密后的密码
self.password.text = [userDefaults objectForKey:kPasswordKey];
}
|
抽取出存储数据的方法 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
- (
void
)saveLocalUserInfo {
// 1. 实例化偏好设置对象
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
// 2. 存储用户名
[userDefaults setObject:self.userName.text forKey:kUserNameKey];
// 3. 将密码进行base64 加密
// 将密码转化为二进制数据
NSData *data = [self.password.text dataUsingEncoding:NSUTF8StringEncoding];
// 进行加密
NSString *base64Str = [data base64EncodedStringWithOptions:0];
// 4. 将加密后的密码存储到偏好设置
[userDefaults setObject:base64Str forKey:kPasswordKey];
// 5. 为了保证线程的一致性,无论是存储还是读取数据,都要进行同步
[userDefaults synchronize];
}
|
在点击事件中进行登录操作 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
- (IBAction)btnLoginDidClick:(UIButton *)sender {
// 如果两个文本框均不为空,则进行登录操作
if
(self.userName.text.length && self.password.text.length) {
// 1. 创建请求
NSString *urlString = @
"http://localhost/login/login.php"
;
NSURL *url = [NSURL URLWithString:urlString];
// POST 请求需要手动设置请求方法,因此为可变请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 设置请求方法
request.HTTPMethod = @
"POST"
;
// 设置请求参数
NSString *body = [NSString stringWithFormat:@
"username=%@&password=%@"
, self.userName.text, self.password.text];
// 将字符串转为二进制数据
NSData *bodyData = [body dataUsingEncoding:NSUTF8StringEncoding];
// 设置请求主体(二进制数据)
request.HTTPBody = bodyData;
// 2. 发送请求
[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
// 打印请求结果
NSLog(@
"data:%@"
, [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
// 判断是否登录成功
if
(data && !error) {
NSLog(@
"网络请求成功!"
);
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
if
(dict[@
"userID"
]) {
[self saveLocalUserInfo];
}
//跳转到app主界面,在主线程中发送通知
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:@
"loginSuccess"
object:nil];
});
}
else
{
NSLog(@
"网络请求失败!"
);
}
}] resume];
}
else
{
NSLog(@
"用户名或密码不能为空!"
);
}
}
|
C. 实现页面间跳转 。
在AppDelegate.m文件中利用通知设置页面的跳转 。
切换的主方法 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
- (
BOOL
)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 1. 注册登录成功的通知观察者
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(loginSuccess) name:@
"loginSuccess"
object:nil];
// 2. 注册登录成功的通知观察者
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(logoutSuccess) name:@
"logoutSuccess"
object:nil];
// 每次app打开后,应该展示给用户哪个界面
// 3. 利用偏好设置中用户保存的信息来判断用户的登录状态
NSString *userName = [[NSUserDefaults standardUserDefaults] objectForKey:kUserNameKey];
NSString *password = [[NSUserDefaults standardUserDefaults] objectForKey:kPasswordKey];
if
(userName && password) {
// 显示app 主界面
[self loginSuccess];
}
else
{
[self logoutSuccess];
}
return
YES;
}
|
登录成功 。
1
2
3
4
5
6
7
|
- (
void
)loginSuccess {
NSLog(@
"登录成功!"
);
// 获取主界面
UIStoryboard *mainSb = [UIStoryboard storyboardWithName:@
"Main"
bundle:nil];
// 切换控制器
self.window.rootViewController = mainSb.instantiateInitialViewController;
}
|
注销成功 。
1
2
3
4
5
6
7
|
- (
void
)logoutSuccess {
NSLog(@
"注销成功!"
);
// 获取登录界面
UIStoryboard *loginSb = [UIStoryboard storyboardWithName:@
"Login"
bundle:nil];
// 切换控制器
self.window.rootViewController = loginSb.instantiateInitialViewController;
}
|
在Main.storyboard关联的控制器中设置注销按钮的点击事件 。
1
2
3
4
5
6
7
|
// 1. 清除本地信息
[[NSUserDefaults standardUserDefaults] removeObjectForKey:kUserNameKey];
[[NSUserDefaults standardUserDefaults] removeObjectForKey:kPasswordKey];
// 同步信息
[[NSUserDefaults standardUserDefaults] synchronize];
// 2. 发送信息,切换控制器
[[NSNotificationCenter defaultCenter] postNotificationName:@
"logoutSuccess"
object:nil];
|
三. Token值介绍 。
四. MD5加密--(信息-摘要算法) 哈希算法之一 。
把一个任意长度的字节串变换成一定长度的十六进制的大整数. 。
注意,字符串的转换过程是不可逆的,不能通过加密结果,反向推导出原始内容 。
基本介绍 。
需要导入第三方框架: NSString+Hash 。
MD5特点
MD5 应用
使用方法 。
利用 MD5 对字符串进行加密 。
1
2
3
|
NSString *password = @
"WangPengfei"
;
password = [password md5String];
NSLog(@
"password1:%@"
, password);
|
加盐:可以保证 MD5加密之后更加安全 。
1
2
3
4
|
NSString *salt = @
"234567890-!@#$%^&*()_+QWERTYUIOP{ASDFGHJKL:XCVBNM<>"
;
[password stringByAppendingString:salt];
password = [password md5String];
NSLog(@
"password2:%@"
, password);
|
每一个公司都有自己的“盐值”,盐值越复杂,越安全 。
五. 时间戳密码 。
基本介绍 。
使用步骤 。
获取MD5 首次加密的密码 。
1
2
3
4
|
// 1. 当前密码
NSString *password = @
"zhang"
;
// 2. hmacKey值,是对“WangPengfei” 进行 MD5加密之后的值(动态生成的)
NSString *hmacKey = @
"d3bba33b51acaa0a272de7a2f6dfa233"
;
|
加密过程 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
// 1. 第一次加密:第一次 HMAC 运算
password = [password hmacMD5StringWithKey:hmacKey];
// 2.1 获得当前的时间
NSDate *date = [NSDate date];
// 2.2 获得当前时间的字符串
// 实例化时间格式器
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
// 设置时间格式
formatter.dateFormat = @
"yyyy-MM-dd HH:mm"
;
// 获取当前时间(要和服务器保持一致)
NSString *dateStr = [formatter stringFromDate:date];
// 3. 将第一次加密后的密码与当前时间的字符串拼接在一起
password = [password stringByAppendingString:dateStr];
// 4. 进行第二次 HMAC 加密
password = [password hmacMD5StringWithKey:hmacKey];
|
访问 loginhmac.php 接口,发送请求 。
创建请求 。
1
2
3
4
5
6
7
8
|
NSURL *url = [NSURL URLWithString:@
"http://localhost/login/loginhmac.php"
];
// POST 要手动设置方法,因此为可变
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 设置请求方法
request.HTTPMethod = @
"POST"
;
// 设置请求体内容
NSString *body = [NSString stringWithFormat:@
"username=zhangsan&password=%@"
, password];
request.HTTPBody = [body dataUsingEncoding:NSUTF8StringEncoding];
|
发送请求 。
1
2
3
|
[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@
"%@"
, [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
}] resume];
|
六. 钥匙串访问 。
基本介绍 。
简单使用 。
参数介绍 。
Password :需要存储的密码信息. 。
Service :用来标识 app ,app的唯一标识符. 。
account :账户信息,当前密码所对应的账号. 。
利用钥匙串进行加密 。
1
2
3
4
|
// 获取应用程序唯一标识.
NSString *bundleId = [NSBundle mainBundle].bundleIdentifier;
// 利用第三方框架,将用户密码保存在钥匙串
[SSKeychain setPassword:self.pwdText.text forService:bundleId account:@
"wpf"
];
|
从钥匙串加载密码 。
1
|
self.pwdText.text = [SSKeychain passwordForService:bundleId account:@
"wpf"
];
|
七. 指纹识别 。
简单介绍 。
使用步骤 。
导入框架 。
1
|
#import <LocalAuthentication/LocalAuthentication.h>
|
获得当前系统版本号 。
1
2
3
4
5
|
float
version = [UIDevice currentDevice].systemVersion.floatValue;
if
(version < 8.0 )
// 判断当前系统版本 {
NSLog(@
"系统版本太低,请升级至最新系统"
);
return
;
}
|
实例化指纹识别对象,判断当前设备是否支持指纹识别功能(是否带有TouchID) 。
1
2
3
4
5
6
7
8
|
// 1> 实例化指纹识别对象
LAContext *laCtx = [[LAContext alloc] init];
// 2> 判断当前设备是否支持指纹识别功能.
if
(![laCtx canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:NULL]) {
// 如果设备不支持指纹识别功能
NSLog(@
"该设备不支持指纹识别功能"
);
return
;
};
|
指纹登陆(默认是异步方法) 。
1
2
3
4
5
6
7
8
|
[laCtx evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:@
"指纹登陆"
reply:^(
BOOL
success, NSError *error) {
// 如果成功,表示指纹输入正确.
if
(success) {
NSLog(@
"指纹识别成功!"
);
}
else
{
NSLog(@
"指纹识别错误,请再次尝试"
);
}
}];
|
源码下载:
GitHub源码 。
总结 。
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我的支持.
原文链接:http://www.jianshu.com/p/422e97e60f2d 。
最后此篇关于iOS中常见的几种加密方法总结的文章就讲到这里了,如果你想了解更多关于iOS中常见的几种加密方法总结的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
1、定义 设 \(u\) 和 \(v\) 为一张图上的任意两个节点。令 \(c(u, v)\) 为它们之间的边的容量, \(f(u, v)\) 为它们之间的流量,则需要满足以
1、前言 工作中涉及到文件系统,有时候需要判断文件和目录是否存在。我结合apue第四章文件和目录,总结一下如何正确判断文件和目录是否存在,方便以后查询。 2、stat系列函数 stat函数用来
并查集(Union-Find Set): 一种用于管理分组的数据结构。它具备两个操作:(1)查询元素a和元素b是否为同一组 (2) 将元素a和b合并为同一组。 注意:并查集不能将在同一组的元素拆
当下,注解非常流行,以前很长篇的代码,现在基本上一个注解就能搞定。 那,在Mybatis中又有哪些注解呢? Mybatis中的注解基本上都在org.apache.ibatis.annotat
指针操作数组,方法一是p+index,方法二是p[index],第二种方法跟数组访问方法是一样的。 数组引用返回的是数组的第一个元素的指针地址。 可以将指针指向数组的任意元素,然后从那里开始访问
通常部署完php环境后会进行一些安全设置,除了熟悉各种php漏洞外,还可以通过配置php.ini来加固PHP的运行环境,PHP官方也曾经多次修改php.ini的默认设置。 下面对php.ini中一
在JavaScript中,使用typeof可以检测基本数据类型,使用instanceof可以检测引用数据类型。在PHP中,也有检测数据类型的方法,具体如下: 1、输出变量的数据类型(gettype
把图片缓存到本地,在很多场景都会用到,如果只是存储文件信息,那建一个plist文件,或者数据库就能很方便的解决问题,但是如果存储图片到沙盒就没那么方便了。这里简单介绍两种保存图片到沙盒的方法。
(1)需要安装docker容器,在docker容器内安装jenkins,gogs,tomcat。 新建maven项目,添加findbugs plugin。 使用docker
今天主题是实现并发服务器,实现方法有多种版本,先从简单的单进程代码实现到多进程,多线程的实现,最终引入一些高级模块来实现并发TCP服务器。 说到TCP,想起吐槽大会有个段子提到三次握手,也只有程序
如下所示: Ctrl+1或F2快速修复 Ctrl+D快捷删除行 Shift+Enter 快速切换到下一行,在本行的任何位置都可 Ctrl+F11快速运行代码 Alt+上下键 快速移动行(可
JSP是Servlet技术的扩展,本质上是Servlet的简易方式,更强调应用的外表表达。 JSP编译后是”类servlet”。 Servlet和JSP最主要的不同点在于,Servlet的应用逻辑
Java中的Runable,Callable,Future,FutureTask,ExecutorService,Excetor,Excutors,ThreadPoolExcetor在这里对这些关键
读取Java文件到byte数组的三种方法(总结) ? 1
用java实现的数组创建二叉树以及递归先序遍历,递归中序遍历,递归后序遍历,非递归前序遍历,非递归中序遍历,非递归后序遍历,深度优先遍历,广度优先遍历8种遍历方式:
1、简明总结 ASCII(char) 返回字符的ASCII码值 BIT_LENGTH(str) 返回字符串的比特长度 CONCAT(s1,s2…,sn)
java应用服务器(web server),是指运行java程序的web应用服务器软件,不包括nginx、Apache等通用web服务器软件。 一、Tomcat Tomcat是Apache 软件基
事务作为抽象层,允许应用忽略DB 内部一些复杂并发问题和某些硬件、软件故障,简化应用层的处理逻辑:事务中止(transaction abort),而应用仅需重试。对复杂访问模式,事务可大大减少需要考虑
我们在本教程学习了如何描述 XML 文档的结构 我们学习到了如何使用 DTD 来定义一个 XML 文档的合法元素,以及如何在我们的 XML 内部或者作为一个外部引用来声明 DTD 我们学习了如何为
在这个XPath 基础教程中我们讲解了如何在 XML 文档中查找信息 我们可以使用 XPath 的元素和属性在 XML 文档中进行导航 我们也学习了如何使用 XPath 中内建的某些标准函数 如
我是一名优秀的程序员,十分优秀!