123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141 |
- //
- // SLKeyChain.m
- // DarkMode
- //
- // Created by wsl on 2020/6/15.
- // Copyright © 2020 https://github.com/wsl2ls ----- . All rights reserved.
- //
- #import "SLKeyChain.h"
- #import <Security/SecItem.h>
- #import <Security/SecBase.h>
- NSString* const SLkeychainService = @"com.wsl.ios.keychain";
- static NSString* const keychainErrorDomain = @"com.wsl.ios.keychain.errorDomain";
- static NSInteger const kErrorCodeKeychainSomeArgumentsInvalid = 1000; //! 传入的部分参数无效
- @implementation SLKeyChain
- ///更新钥匙串中的用户名和密码
- + (NSError *)updateKeychainWithService:(NSString *)service account:(NSString *)account password:(NSString *)password {
-
- if (!account || !password || !service) {
- NSError *error = [self errorWithErrorCode:kErrorCodeKeychainSomeArgumentsInvalid];
- return error;
- }
- NSDictionary *queryItems = @{(id)kSecClass: (id)kSecClassGenericPassword,
- (id)kSecAttrService: service,
- (id)kSecAttrAccount: account
- };
- NSData *passwordData = [password dataUsingEncoding:NSUTF8StringEncoding];
- NSDictionary *updatedItems = @{
- (id)kSecValueData: passwordData,
- };
- OSStatus updateStatus = SecItemUpdate((CFDictionaryRef)queryItems, (CFDictionaryRef)updatedItems);
- return [self errorWithErrorCode:updateStatus];
- }
- ///删除用户信息
- + (NSError *)deleteWithService:(NSString *)service account:(NSString *)account {
-
- if (!service || !account) {
- return [self errorWithErrorCode:kErrorCodeKeychainSomeArgumentsInvalid];
- }
- NSDictionary *deleteSecItems = @{
- (id)kSecClass: (id)kSecClassGenericPassword,
- (id)kSecAttrService: service,
- (id)kSecAttrAccount: account
- };
- OSStatus errorCode = SecItemDelete((CFDictionaryRef)deleteSecItems);
- return [self errorWithErrorCode:errorCode];
- }
- ///查询用户信息 查到的结果存在NSError中
- + (NSError *)queryKeychainWithService:(NSString *)service account:(NSString *)account {
-
- if (!service || !account) {
- return [self errorWithErrorCode:kErrorCodeKeychainSomeArgumentsInvalid];
- }
- NSDictionary *matchSecItems = @{
- (id)kSecClass: (id)kSecClassGenericPassword,
- (id)kSecAttrService: service,
- (id)kSecAttrAccount: account,
- (id)kSecMatchLimit: (id)kSecMatchLimitOne,
- (id)kSecReturnData: @(YES)
- };
- CFTypeRef dataRef = nil;
- OSStatus errorCode = SecItemCopyMatching((CFDictionaryRef)matchSecItems, (CFTypeRef *)&dataRef);
- if (errorCode == errSecSuccess) {
- NSString *password = [[NSString alloc] initWithData:CFBridgingRelease(dataRef) encoding:NSUTF8StringEncoding];
- return [self errorWithErrorCode:errSecSuccess errorMessage:password];
- }
- return [self errorWithErrorCode:errorCode];
- }
- ///保存用户信息
- + (NSError *)saveKeychainWithService:(NSString *)service account:(NSString *)account password:(NSString *)password {
-
- if (!account || !password || !service) {
- NSError *error = [self errorWithErrorCode:kErrorCodeKeychainSomeArgumentsInvalid];
- return error;
- }
-
- NSError *queryError = [self queryKeychainWithService:service account:account];
- if (queryError.code == errSecSuccess) {
- // update
- return [self updateKeychainWithService:service account:account password:password];
- }
-
- NSData *passwordData = [password dataUsingEncoding:NSUTF8StringEncoding];
- // save
- NSDictionary *saveSecItems = @{(id)kSecClass: (id)kSecClassGenericPassword,
- (id)kSecAttrService: service,
- (id)kSecAttrAccount: account,
- (id)kSecValueData: passwordData
- };
- OSStatus saveStatus = SecItemAdd((CFDictionaryRef)saveSecItems, NULL);
- return [self errorWithErrorCode:saveStatus];
- }
- ///错误信息
- + (NSError *)errorWithErrorCode:(OSStatus)errorCode {
-
- NSString *errorMsg = nil;
-
- switch (errorCode) {
- case errSecSuccess: {
- NSLog(@"操作成功");
- return nil;
- break;
- }
- case kErrorCodeKeychainSomeArgumentsInvalid:
- errorMsg = NSLocalizedString(@"参数无效", nil);
- break;
- case errSecDuplicateItem: // -25299
- errorMsg = NSLocalizedString(@"The specified item already exists in the keychain. ", nil);
- break;
- case errSecItemNotFound: // -25300
- errorMsg = NSLocalizedString(@"The specified item could not be found in the keychain. ", nil);
- break;
- default: {
- if (@available(iOS 11.3, *)) {
- errorMsg = (__bridge_transfer NSString *)SecCopyErrorMessageString(errorCode, NULL);
- }
- break;
- }
- }
- NSDictionary *errorUserInfo = nil;
- if (errorMsg) {
- errorUserInfo = @{NSLocalizedDescriptionKey: errorMsg};
- NSLog(@"%s--Line:%d--错误码:%d--错误信息:%@", __FUNCTION__, __LINE__, errorCode, errorMsg);
- }
- return [NSError errorWithDomain:keychainErrorDomain code:kErrorCodeKeychainSomeArgumentsInvalid userInfo:errorUserInfo];
- }
- + (NSError *)errorWithErrorCode:(OSStatus)errCode errorMessage:(NSString *)errorMsg {
-
- if (errCode == errSecSuccess && errorMsg) {
- NSLog(@"操作成功");
- return [NSError errorWithDomain:keychainErrorDomain code:errSecSuccess userInfo:@{NSLocalizedDescriptionKey: errorMsg}];
- } else {
- return [self errorWithErrorCode:errCode];
- }
- }
- @end
|