iOS开发中用户密码应该保存在哪里
2016-09-10 15:27
316 查看
iOS开发中用户密码应该保存在哪里
字数1413 阅读3488 评论14 喜欢48如果要实现自动登录,不必每次打开应用都去登录,我们势必要把密码保存到本地。
一般我们的操作是:
每次打开应用后,如果存在密码,直接进入界面,然后再进行后台密码验证。如果没网络,我们可以跳过验证;如果有网络,我们可以后台去验证帐号密码的正确性,并根据服务器的response做一些操作。
为什么直接把密码存储在NSUserDefaults中不安全?
iOS中沙盒有哪几个文件夹,都是用来干吗的
默认情况下,每个沙盒含有3个文件夹:Documents, Library 和 tmp。因为应用的沙盒机制,应用只能在几个目录下读写文件Documents:苹果建议将程序中建立的或在程序中浏览到的文件数据保存在该目录下,iTunes备份和恢复的时候会包括此目录
Library:存储程序的默认设置或其它状态信息;
Library/Caches:存放缓存文件,iTunes不会备份此目录,此目录下文件不会在应用退出删除
tmp:提供一个即时创建临时文件的地方。
获取到沙盒Library路径
//获取Library目录路径 - (void)getLibraryPath { NSArray * pathArray = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,NSUserDomainMask, YES); NSString * libraryStrPath = [pathArray objectAtIndex:0]; NSLog(@"LibraryPath:%@“,libraryStrPath); }
如图就是NSUserDefaults对应的plist文件在sandbox中的位置
蓝色部分为plist文件
如果sandbox被破解,或者你的手机被越狱,那么就能轻松拿到这个文件。
那么就能轻松读到存储的信息,密码就会不安全:
在plist中可以找到密码
这对于其它保存在NSUserDefaults中的信息也是一样的,所以对于存在NSUserDefaults中的东西,最好混淆加密一下再存储。
如何删除NSUserDefaults对应的plist文件?
其实就是删除plist文件中所有的键值对。NSUserDefaults *userDefatluts = [NSUserDefaults standardUserDefaults]; NSDictionary *dictionary = [userDefaults dictionaryRepresentation]; for(NSString* key in [dictionary allKeys]){ [userDefaults removeObjectForKey:key]; [userDefaults synchronize]; }
如何解决“直接把密码存储在NSUserDefaults中不安全”的问题?
把密码加密后再存储到NSUserDefaults中
iOS中提供了很多种加密算法,对于存储密码,可以使用不可逆的MD5加密。使用MD5加密需要导入头文件:
''#import <CommonCrypto/CommonDigest.h>
##### 简单的MD5加密 + ( NSString *)md5String:( NSString *)str { const char *myPasswd = [str UTF8String ]; unsigned char mdc[ 16 ]; CC_MD5 (myPasswd, ( CC_LONG ) strlen (myPasswd), mdc); NSMutableString *md5String = [ NSMutableString string ]; for ( int i = 0 ; i< 16 ; i++) { [md5String appendFormat : @"%02x" ,mdc[i]]; } return md5String; } ##### 复杂一些的MD5加密 + ( NSString *)md5String:( NSString *)str { const char *myPasswd = [str UTF8String ]; unsigned char mdc[ 16 ]; CC_MD5 (myPasswd, ( CC_LONG ) strlen (myPasswd), mdc); NSMutableString *md5String = [ NSMutableString string ]; [md5String appendFormat : @"%02x" ,mdc[ 0 ]]; for ( int i = 1 ; i< 16 ; i++) { [md5String appendFormat : @"%02x" ,mdc[i]^mdc[ 0 ]];
不使用NSUserDefaults保存密码,使用keyChain来保存密码
更加保险的方法是把密码保存在iOS提供的keychina中,并且删除应用后,密码不会删除,下载安装还能使用。iOS系统提供了一些方法,进行一些简单的封装之后,就可以很方便的使用。封装后可供使用的几个类
Github-chenhuaizhe-iOS-keychain
你也可以在这里直接下载,更多交流可以关注我的微博:@陈怀哲
下面是封装代码,使用时需要先导入Security.framework:
PassWordTool.h
#import <Foundation/Foundation.h> @interface PassWordTool : NSObject /** * @brief 存储密码 * * @param password 密码内容 */ +(void)savePassWord:(NSString *)password; /** * @brief 读取密码 * * @return 密码内容 */ +(id)readPassWord; /** * @brief 删除密码数据 */ +(void)deletePassWord; @end
PassWordTool.m
import "PassWordTool.h" import "KeychainTool.h" @implementation PassWordTool static NSString * const KEY_IN_KEYCHAIN = @"com.chenyuan.app.userid"; static NSString * const KEY_PASSWORD = @"com.chenyuan.app.password"; +(void)savePassWord:(NSString *)password { NSMutableDictionary *usernamepasswordKVPairs = [NSMutableDictionary dictionary]; [usernamepasswordKVPairs setObject:password forKey:KEY_PASSWORD]; [KeychainTool save:KEY_IN_KEYCHAIN data:usernamepasswordKVPairs]; } +(id)readPassWord { NSMutableDictionary *usernamepasswordKVPair = (NSMutableDictionary *)[KeychainTool load:KEY_IN_KEYCHAIN]; return [usernamepasswordKVPair objectForKey:KEY_PASSWORD]; } +(void)deletePassWord { [KeychainTool delete:KEY_IN_KEYCHAIN]; } @end
KeychainTool.h
#import <Foundation/Foundation.h> @interface KeychainTool : NSObject + (NSMutableDictionary *)getKeychainQuery:(NSString *)service ; + (void)save:(NSString *)service data:(id)data ; + (id)load:(NSString *)service ; + (void)delete:(NSString *)service ; @end
KeychainTool.m
``` # import "KeychainTool.h" @implementation KeychainTool + (NSMutableDictionary *)getKeychainQuery:(NSString *)service { return [NSMutableDictionary dictionaryWithObjectsAndKeys: (__bridge_transfer id)kSecClassGenericPassword,(__bridge_transfer id)kSecClass, service, (__bridge_transfer id)kSecAttrService, service, (__bridge_transfer id)kSecAttrAccount, (__bridge_transfer id)kSecAttrAccessibleAfterFirstUnlock,(__bridge_transfer id)kSecAttrAccessible, nil]; } + (void)save:(NSString *)service data:(id)data { //Get search dictionary NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; //Delete old item before add new item SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery); //Add new object to search dictionary(Attention:the data format) [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(__bridge_transfer id)kSecValueData]; //Add item to keychain with the search dictionary SecItemAdd((__bridge_retained CFDictionaryRef)keychainQuery, NULL); } + (id)load:(NSString *)service { id ret = nil; NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; //Configure the search setting [keychainQuery setObject:(id)kCFBooleanTrue forKey:(__bridge_transfer id)kSecReturnData]; [keychainQuery setObject:(__bridge_transfer id)kSecMatchLimitOne forKey:(__bridge_transfer id)kSecMatchLimit]; CFDataRef keyData = NULL; if (SecItemCopyMatching((__bridge_retained CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) { @try { ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge_transfer NSData *)keyData]; } @catch (NSException *e) { NSLog(@"Unarchive of %@ failed: %@", service, e); } @finally { } } return ret; } + (void)delete:(NSString *)service { NSMutableDictionary *keychainQuery = [self getKeychainQuery:service]; SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery); } @end
服务器密码验证登录请求
验证请求时,最好是不直接把明文密码包含在请求里面。可以根据一系列字符串生成MD5加密后的签名,根据user-id 和 签名来验证登录。
比如:
NSString *sourceStr = [NSString stringWithFormat:@"attach=iOS&chartset=utf-8&format=json&partner=google&userid=%@&password=%@”,userid,password]; NSString *signStr = [NSString md5String:sourceStr];
这样得到的signStr和userid再作为网络请求的参数传给服务器做验证。
相关文章推荐
- iOS开发中用户密码应该保存在哪里
- iOS开发中用户密码应该保存在哪里
- IOS学习之iOS开发中用户密码应该保存在哪里
- 在ios开发中,使用钥匙来保存用户密码和账号
- iOS:iOS开发中用户密码保存位置
- iOS开发中——如何保存用户敏感信息(用户名和密码等信息)
- iOS:iOS开发中用户密码保存位置
- iOS开发之----两种保存用户名和密码实现记住密码库
- C/S模式的程序,用户信息应该保存在哪里呢?
- 【iOS开发-74】解决方案:Xcode6下利用preference保存数据,最终的plist文件在哪里?
- ios开发,用户登录界面,输入用户名之后点击Next后切换到密码输入框,密码输入框输入后点击Return,键盘回收
- iOS开发小点之--使用Keychain保存用户名密码
- IOS开发之----两种保存用户名和密码实现记住密码库
- 【iOS开发-74】解决方式:Xcode6下利用preference保存数据,终于的plist文件在哪里?
- ios实现用户登录的保存密码功能
- Android开发之保存用户的登陆密码
- iOS 开发中用户记住账户,密码
- iOS开发--利用keychain保存用户数据
- ios实现用户登录的保存密码功能
- IOS开发之----两种保存用户名和密码实现记住密码库