分享一个牛人写的加密分类,注释相当清晰。
加密方案
方案一:直接 MD5 非常不安全 (穷举破解)
pwd = pwd.md5String;
方案二 MD5 + 盐 盐值要够`咸`,可以从服务器获取
pwd = [pwd stringByAppendingString:@"无规律复杂的盐"].md5String;
安全方案三 - HMAC
pwd = [pwd hmacMD5StringWithKey:@"key"];
相对之前的方案,安全级别要高很多,使用 `key` 对 pwd 进行`加密`,然后在进行 md5,然后再次加密,再次 md5
安全方案四 - 时间戳密码(本地时间与服务器可能不一致,最好从服务器获取时间)
保证了不同时间传输的密码都是不一样的,服务器判断时要判断当前 分钟和前一分钟。密码有效期为两分钟。
// 对密码进行时间戳加密
- (NSString*)timePassword:(NSString*) pwd{
// 1.生成key 的 md5
NSString *key = @"weijing_yun".md5String;
NSLog(@"key: %@", key);
// 2.用key 对密码进行hmac 加密
NSString *pwdkey = [pwd hmacMD5StringWithKey:key];
// 3. 取当前的服务器系统时间 以变后面加时间戳
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/hmackey.php"];
// 使用同步获取时间
NSData *data = [NSData dataWithContentsOfURL:url];
// 反序列化
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
//取出日期字符串
NSString *dateStr = dict[@"key"];
NSLog(@"时间%@", dateStr);
// 4.密码 + 时间戳
pwdkey = [pwdkey stringByAppendingString:dateStr];
NSLog(@"%@" , pwdkey);
// 5.再次使用 hmac 加密
return [pwdkey hmacMD5StringWithKey:key];
}
修改 , 上面代码存在一个问题 , 如果没有联网,会卡死。下面将网络请求放在异步线程,获取时间后
再调用登陆
- (IBAction)loginClick:(id)sender {
// 关闭键盘
[self.view endEditing:YES];
[self timePassword:self.pwd.text finished:^(NSString *loginKey) {
[self login:loginKey];
}];
}
// 对密码进行时间戳加密
- (void)timePassword:(NSString*) pwd finished:(void (^)(NSString *loginKey))finished;{
// 1.生成key 的 md5
NSString *key = @"weijing_yun".md5String;
// 2.用key 对密码进行hmac 加密
__block NSString *pwdkey = [pwd hmacMD5StringWithKey:key];
// 3. 取当前的服务器系统时间 以变后面加时间戳
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/hmackey.php"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (data == nil | connectionError != nil) {
NSLog(@"网络过程");
return ;
}
// 获取时间 , 进行加密 反序列化
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
//取出日期字符串
NSString *dateStr = dict[@"key"];
NSLog(@"时间%@", dateStr);
// 4.密码 + 时间戳
pwdkey = [pwdkey stringByAppendingString:dateStr];
// NSLog(@"%@" , pwdkey);
// 5.再次使用 hmac 加密
pwdkey = [pwdkey hmacMD5StringWithKey:key];
// 将加密内容传到 login 登陆
finished(pwdkey);
}];
}
- (void)login:(NSString*) pwd{
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/loginhmac.php"];
NSMutableURLRequest *requst = [NSMutableURLRequest requestWithURL:url cachePolicy:1 timeoutInterval:15];
// 请求类型
requst.HTTPMethod = @"POST";
// 设置要发送的二进制数
NSString *str = [NSString stringWithFormat:@"username=%@&password=%@" , self.userName.text , pwd];
requst.HTTPBody = [str dataUsingEncoding:NSUTF8StringEncoding];
// 发送请求
[NSURLConnection sendAsynchronousRequest:requst queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
if (data == nil | connectionError != nil) {
NSLog(@"网络故障");
return ;
}
NSDictionary *aa = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
if ([aa[@"userId"] intValue ] > 0) {
// 登陆成功 本地保存密码 账户
[self saveUserInfo];
NSLog(@"成功登陆");
}else {
NSLog(@"失败");
}
}];
}