- 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的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
新建表: create table [表名] ( [自动编号字段] int IDENTITY (1,1)&nbs
我的文件中有正在本地化的字符串。其中许多是常见的,并且已经在整个 iOS 中使用。例如。 “保存”、“加载”、“返回”、“收藏夹”、“拍照”。为了与其他应用程序和内置应用程序提供一致的用户体验,是否有
我已经学习了 Qt 的基础知识,现在对这个漂亮的库的深度感兴趣。请帮助我理解: 所有类都是从QObject派生的吗? 为什么可以在QWidget(和派生类)上绘画? return app.exec()
我在 webpack 中设置了一个自调用函数,并使用常见的 JS 来需要一些包: (function() { var $ = require("jquery"); //...my functi
我正在尝试制作一个大量使用词性标记的应用程序。但是 nltk 的 pos 标记功能对我来说似乎不符合标准 - 例如: import nltk text = "Obama delivers his fi
有没有办法处理发送到 MySQL 的常见查询以防止不必要的带宽使用? 最佳答案 选项是: 使用MySQL缓存查询 好:全自动 差:仍然需要访问数据库服务器;有一次缓存让我在一个项目中失望,花了很长时间
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 4 年前。 Improve this qu
关闭。这个问题需要debugging details .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 6年前关闭。 Improve this questio
我正在尝试调用返回 csv 文件的网络服务。因此,我调用的每个 URL 都有一个后缀,它是一个字符串,表示要生成哪个 csv。然后我想将此 csv 保存到文件中。有很多要生成,所以我从多个线程调用此类
流行手机型号支持的典型触摸点数量是多少?我在基础研究中看到低至 2 和高至 5,但我希望能够将其映射到实际手机和更好的限制! 最佳答案 两部手机的触控点数据: Galaxy S 5 LG
出于好奇 - 我知道有 LAMP - Linux、Apache、MySQL 和 PHP。但是还有哪些其他 Web 堆栈替代方案的缩写呢?像 LAMR - Linux、Apache、MySQL Ruby
我写了一个java代码(使用apache common vfs2)来上传文件到SFTP服务器。最近,我在我的服务器上引入了 PGP 安全性。现在,java 代码无法连接到该服务器。与 FileZill
由于 GLU 被认为对于现代 OpenGL (3.1+) 来说已经过时,那么使用 C/C++ 在 OpenGL 中绘制基本形状(例如椭圆或弧线/饼图)的方法是什么?令人难以置信的是,在 OpenGL
我想知道是否有最流行的 iOS 应用程序的自定义 URL 方案列表,例如 Keynote、Numbers、Pages、Evernote 等。我还想知道这些应用程序使用什么参数网址。 我需要这个的原因是
我正在使用 NDK r10d 移植 C++ myToll Linux 应用程序以在 Android 上运行。 (请注意,这不是带有 apk 的 Android 应用程序,而是从 shell 运行的实用
假设您想要使用 UML 2 部署图为在该领域没有太多知识的人可视化一个常见的 PHP 服务器应用程序。这样一个通用的应用程序可能有三个设备节点(数据库服务器、Web 服务器和客户端)和四个执行环境节点
我正在尝试运行以下代码,以找到两个人之间的共同 friend 。输入如下 A : B C D B : A C D E C : A B D E D : A B C E E : B C D 我无法在输出文
我在 Gitolite 的 manual 中找到的唯一东西在钩子(Hook)上,是: If you want to add your own hook, it's easy as long as it
具体来说,我有一个问题,在 AWS 环境中组织 AZ 故障转移的推荐方法是什么。此外,最好了解典型的 AWS 故障以组织应用程序 HA(高可用性)。 因此,应用程序架构(AWS 服务使用)如下: 它或
我正在尝试编写一个通用的 SecurePagingAndSorting 存储库,它将检查 CRUD 操作的安全性,以节省在所有 JPA 存储库中重复相同的 PreAuthorize(使用不同的权限)。
我是一名优秀的程序员,十分优秀!