为了使保存的本地密码更安全,我们需要使用钥匙串进行保存本地加密后的密码,苹果7.03之后自带了钥匙串。但是使用比较麻烦,全部使用c语言。我们可以使用别人封装好的SSKeychain框架即可使用,具体用法如下:
导入SSKeychain框架后可以直接使用的常用方法:
删除保存在钥匙串里的密码(很少用)
+ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account;
+ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error;
获得保存在钥匙串里的密码
参数:
第一个参数:用户密码的明文
第二个参数:登录的服务名(在钥匙串中访问独立)
第三个参数:用户的用户名
+ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account;
+ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error;
将密码保存在钥匙串中
+ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account;
+ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error;
获得保存在钥匙串里的所有服务信息,但是没有密码
+ (NSArray *)allAccounts;
具体代码如下:
先拖进SSKeyChain框架,工程使用如下:
<span style="font-size:18px;">//
// ViewController.m
// POST登录
//
// Created by apple on 15/10/28.
// Copyright (c) 2015年 LiuXun. All rights reserved.
//
/** 导入SSKeychain框架后可以直接使用的常用方法:
删除保存在钥匙串里的密码(很少用)
+ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account;
+ (BOOL)deletePasswordForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error;
获得保存在钥匙串里的密码
+ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account;
+ (NSString *)passwordForService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error;
将密码保存在钥匙串中
+ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account;
+ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account error:(NSError **)error;
获得保存在钥匙串里的所有服务信息,但是没有密码
+ (NSArray *)allAccounts;
*/
/**
加密的原则:
1、在网络传输过程中,没有传递带密码的明文(md5+hmac+加盐)
2、在本地没有存储密码的明文(钥匙串 但是钥匙串只有在7.0.3版本)
*/
#define KLoginUserNameKey @"KLoginUserNameKey"
#define kLoginServiceName @"kLoginServiceName"
#import "ViewController.h"
#import "NSString+Hash.h"
#import "SSKeychain.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UITextField *nameText;
@property (weak, nonatomic) IBOutlet UITextField *pwdText;
@end
@implementation ViewController
-(void)viewDidLoad
{
// 取出用户偏好设置保存的用户信息
self.nameText.text = [[NSUserDefaults standardUserDefaults] stringForKey:KLoginUserNameKey];
NSLog(@"%@", NSHomeDirectory());
// 查看钥匙串里面的服务信息
NSLog(@"%@", [SSKeychain allAccounts]);
// 取出钥匙串里面的信息
if (self.nameText.text.length > 0) {
NSString *pwd = [SSKeychain passwordForService:kLoginServiceName account:self.nameText.text];
self.pwdText.text = pwd;
}
}
// 加盐的方式
static NSString *salt = @"DIUTY$%^$&^&^&&*((%$$)%~!@~~MUE(*&YWYHS{}&*&))()()";
- (IBAction)Click
{
// 对密码进行md5 加密
// 加盐———在国内用的最多
// 注意:盐要足够长,足够复杂,足够保密
NSString *username = self.nameText.text;
//1. 直接加密
// NSString *pass = [self.pwdText.text md5String];
// 2. 加盐的方式
// NSString *pass = [[self.pwdText.text stringByAppendingString:salt] md5String];
// NSLog(@"%@", pass);
// 3. HMAC+MD5 更靠谱 HMAC本身也是一种加密算法
NSString *pass = [self.pwdText.text hmacMD5StringWithKey:@"hello"];
NSLog(@"%@", pass);
// 1. url
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/login.php"];
// 2. POST必须是可变的请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:1 timeoutInterval:2.0f];
request.HTTPMethod = @"POST";
// POST 请求不需要进行百分号转义
NSString *bodyStr = [NSString stringWithFormat:@"username=%@&password=%@",username, pass];
request.HTTPBody = [bodyStr dataUsingEncoding:NSUTF8StringEncoding];
// 3. 连接
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
// 反序列化
NSDictionary *result = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
NSLog(@"%@", result);
if ([result [@"userId"] intValue] >0) {
// 登录成功,记录用户的信息到偏好设置
[[NSUserDefaults standardUserDefaults] setObject:username forKey:KLoginUserNameKey];
// 为了即时保存,需要同步
[[NSUserDefaults standardUserDefaults] synchronize];
//
/**
参数:
第一个参数:用户密码的明文
第二个参数 :登录的服务名(在钥匙串中访问独立)
第三个参数:用户的用户名
*/
[SSKeychain setPassword:self.pwdText.text forService:kLoginServiceName account:self.nameText.text];
}
}];
}
@end</span>
注意:用户账号不需要加密,保存到本地设置即可。密码需要保存到钥匙串。运行结果如下: