- 現在很多人對于安全越來越重視,作為程序猿的我們,也需要在這一方面多下功夫,讓我們APP用戶儲存的私人信息更加的安全,我看到過很多的人寫代碼,雖然明文密碼不會被儲存,經常是儲存服務器返回的一個秘鑰,大部分程序猿就裸存了,直接就存儲在NSUserDefaults里面了,也有些程序猿有對其進行AES或DES加密后再儲存,但是其本身AES或DES的秘鑰都是寫在代碼中的,一旦程序被反編譯,想要獲取的秘鑰也是相當容易的一件事了。
- 蘋果自己本身就有一個方法可以讓我們儲存一些機密的東西,儲存的機制就是將我們需要儲存的東西儲存在鑰匙串??里面,這樣除非整個iOS的安全機制被破解,要不然你儲存的東西就會相對的安全。
下面提供一個工具類KeychainTool用戶存儲
#import <Foundation/Foundation.h>
@interface KeychainTool : NSObject
/**
* 儲存字符串到??鑰匙串
*
* @param sValue 對應的Value
* @param sKey 對應的Key
*/
+ (void)saveKeychainValue:(NSString *)sValue Key:(NSString *)sKey;
/**
* 從??鑰匙串獲取字符串
*
* @param sKey 對應的Key
*
* @return 返回儲存的Value
*/
+ (NSString *)readKeychainValue:(NSString *)sKey;
/**
* 從??鑰匙串刪除字符串
*
* @param sKey 對應的Key
*/
+ (void)deleteKeychainValue:(NSString *)sKey;
@end
#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)saveKeychainValue:(NSString *)sValue Key:(NSString *)sKey
{
//Get search dictionary
NSMutableDictionary *keychainQuery = [self getKeychainQuery:sKey];
//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:sValue] forKey:(__bridge_transfer id)kSecValueData];
//Add item to keychain with the search dictionary
SecItemAdd((__bridge_retained CFDictionaryRef)keychainQuery, NULL);
}
+ (NSString *)readKeychainValue:(NSString *)sKey
{
NSString *ret = nil;
NSMutableDictionary *keychainQuery = [self getKeychainQuery:sKey];
//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 = (NSString *)[NSKeyedUnarchiver unarchiveObjectWithData:(__bridge_transfer NSData *)keyData];
} @catch (NSException *e) {
NSLog(@"Unarchive of %@ failed: %@", sKey, e);
} @finally {
}
}
return ret;
}
+ (void)deleteKeychainValue:(NSString *)sKey {
NSMutableDictionary *keychainQuery = [self getKeychainQuery:sKey];
SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery);
}
@end
最后編輯于 :
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。