iOS open source encrypted album agony implementation (i)

Source: Internet
Author: User

Brief introduction

Although there are some good encryption album app on the market, but not the built-in ads, it is to limit the number of uploads. This paper introduces the production process of an encrypted album, which will include multiple passwords (enter different passwords to access different spaces, can be used to hide), WiFi transmission map, photo file encryption and other functions. Currently the project and the article will go forward at the same time, the project source code can be downloaded on GitHub.
Click to go to GitHub

Overview

This paper mainly introduces the implementation of login verification and registration module of encrypted album. Registration requires only a password, and each password corresponds to a separate storage space, which is verified by Touch ID or password when logged in. If there are multiple sets of passwords, the Touch ID is bound to a master password (can be changed).

Account Data Storage Design account class design

Since the encrypted album is only used locally, the current design has not considered password retrieval, so the account only needs a password field, in order to count the current number of accounts, and then use an ID field, the account class is SGAccount designed as follows.

@interface SGAccount : NSObject <NSSecureCoding>@property (nonatomicassignNSInteger accountId;@property (nonatomicNSString *password;@end

In order to archive storage, it is necessary to implement nscoding methods, as follows.

#import "SGAccount.h" NSString*ConstKsgaccountid = @"Ksgaccountid";NSString*ConstKsgaccountpwd = @"Ksgaccountpwd"; @implementation sgaccount - (void) Encodewithcoder: (Nscoder *) encoder {[Encoder Encodeinteger: Self. AccountIdForkey:ksgaccountid]; [Encoder Encodeobject: Self. PasswordFORKEY:KSGACCOUNTPWD];} -(Instancetype) Initwithcoder: (Nscoder *) Decoder {if( Self= [SuperInit]) { Self. AccountId= [Decoder Decodeintegerforkey:ksgaccountid]; Self. Password= [Decoder decodeobjectforkey:ksgaccountpwd]; }return  Self;} + (BOOL) Supportssecurecoding {return YES;}@end
Account Collection Class Design

For multiple accounts, using an Account collection class to manage all accounts, account collection class to manage all the account, due to login verification needs to query password corresponding to the existence of the account, in order to efficiently find, should use a password key map, that is, nsdictionary to store.
In addition, you need to record the Touch ID corresponding password, in summary, designed as follows.

@interface SGAccountSet : NSObject <NSSecureCoding>@property (nonatomicstrongNSMutableDictionary<NSString *, SGAccount *> *accountMap;@property (nonatomicNSString *touchIDPassword;@end

In the same way, these attributes also need to be handled in nscoding related methods, and the implementation of classes is as follows.

#import "SGAccountSet.h" NSString*ConstKsgaccountsetaccountmap = @"Ksgaccountsetaccountmap";NSString*ConstKsgaccountsettouchidpassword = @"Ksgaccountsettouchidpassword"; @implementation sgaccountset + (BOOL) Supportssecurecoding {return YES;} -(Instancetype) Initwithcoder: (Nscoder *) Decoder {if( Self= [SuperInit]) { Self. Accountmap= [Decoder decodeobjectforkey:ksgaccountsetaccountmap]; Self. Touchidpassword= [Decoder Decodeobjectforkey:ksgaccountsettouchidpassword]; }return  Self;} - (void) Encodewithcoder: (Nscoder *) encoder {[Encoder encodeobject: Self. AccountmapFORKEY:KSGACCOUNTSETACCOUNTMAP]; [Encoder Encodeobject: Self. TouchidpasswordForkey:ksgaccountsettouchidpassword];} - (nsmutabledictionary<NSString*,sgaccount *> *) Accountmap {if(_accountmap = =Nil) {_accountmap = @{}. Mutablecopy; }return_accountmap;}@end

For lazy loading of accountmap, you can guarantee that the dictionary you get when there is no account data is not empty.

Design of public interface for account management class

The interface provided by the

Account management class is mainly registered and verified, and is used as a single case for convenience. The
only need to provide a password when registering, and the verification includes two cases, one is through password authentication, the second is through Touch ID verification, and the account class is returned directly when the verification is successful.
In addition to this, the account management class has an attribute Currentaccount records the account that is currently successfully validated for subsequent use, specifically designed as follows.

 @interface  sgaccountmanager : nsobject   + (Instancetype) sharedmanager;-(void ) Registeraccountwithpassword: (nsstring  *) password errormessage: (nsstring  * __ Autoreleasing *) errormessage;-(Sgaccount *) Getaccountbypwd: (NSString  *) pwd;-( Sgaccount *) Gettouchidaccount; /* * for Appdelegate get the root controller of the window * not registered account then go to the registration page * Registered users go to login Verification page */-(uiviewcontroller  *) Getrootviewcontroller;  @property  (nonatomic , strong ) Sgaccount *currentaccount;  @end   
Private interface Design

The private interface is used to manage the logical implementation within the class, where Accountset is used to store all user data, and Accountpath is used to store the path where the account data is saved and loaded.

@interface SGAccountManager ()@property (nonatomicstrong) SGAccountSet *accountSet;@property (nonatomicNSString *accountPath;@end

lazy loading of account set Accountset
The initialization of the Account Collection class consists of two steps, first loading the data from the hard disk, or initializing one if there is no data on the hard disk. This is broken down into two methods because the method of loading the data from the hard disk Loadaccountset will be called elsewhere, as follows.

- (SGAccountSet *)accountSet {    if (_accountSet == nil) {        [self loadAccountSet];    }    return _accountSet;}- (void)loadAccountSet {    SGAccountSet *set = [NSKeyedUnarchiver unarchiveObjectWithFile:self.accountPath];    if (!set) {        setnew];    }    set;}

lazy loading of account access path Accountpath
The storage path for account data is used when loading and writing account collection class data, as follows.

- (NSString *)accountPath {    ifnil) {        YES) lastObject] stringByAppendingPathComponent:@"account.agony"];    }    return _accountPath;}
Implementation of Registration

When the password is passed in at the time of registration, the password is encrypted to determine if the password already exists in the account collection to prevent the password from being duplicated because the password corresponds to storage space one by one, so the password cannot be duplicated. If the password repeats, it is passed back through the passed-in string pointer.
The password for the first registration will be bound to the Touch ID, which is the equivalent of entering this password later using Touch ID verification, and the registration method is implemented as follows.

- (void) Registeraccountwithpassword: (NSString*) Password errormessage: (NSString* __autoreleasing *) errormessage {nsassert (password! =Nil, @"Password cannot be nil");//cryptographic processing of md5+ salts for passwordsPassword = [ SelfEncryptstring:password]; Sgaccount *account = Self. Accountset. Accountmap[Password];//If the account is available according to the password to be registered, the password is duplicated, the callback error is returned    if(Account! =Nil) {*errormessage = @"Account already Exists";return; } account = [Sgaccount new];//Generate account ID    NsintegerAccountId = Self. Accountset. Accountmap. AllKeys. Count+1; Account. AccountId= AccountId; Account. Password= password;//Deposit into the collection     Self. Accountset. Accountmap[Password] = account;if(AccountId = =1) {//If it is registered for the first time, bind it to the password on the Touch ID verification corresponding         Self. Accountset. Touchidpassword= password; }//Synchronizing the memory data to the hard disk[ SelfSaveaccountset];}

The encryption method is implemented as follows.

- (NSString *)encryptString:(NSString *)string {    return [[[[NSString stringWithFormat:@"allowsad12345%@62232",string] MD5] MD5] MD5];}

The MD5 method is added to the nsstring in the form of a taxonomy, which is implemented as follows.

#import "nsstring+md5.h" #import <CommonCrypto/CommonDigest.h>  @implementation nsstring (MD5)- (NSString*) MD5 {Const Char*CSTR = [ SelfUtf8string];unsigned CharDigest[cc_md5_digest_length]; CC_MD5 (CStr, (Cc_long) strlen (CSTR), Digest);nsmutablestring*result = [nsmutablestringStringwithcapacity:cc_md5_digest_length *2]; for(inti =0; i < cc_md5_digest_length; i++) {[Result appendformat:@"%02x", Digest[i]]; }returnResult;}@end

The method for writing data to the hard disk is implemented as follows.

- (void)saveAccountSet {    [NSKeyedArchiver archiveRootObject:self.accountSet toFile:self.accountPath];}
Implementation of login Verification

Through the password authentication method, the password is encrypted first, and then the password in the collection is matched, then the verification is successful, and the implementation is as follows.

- (SGAccount *)getAccountByPwd:(NSString *)pwd {    pwd = [self encryptString:pwd];    return self.accountSet.accountMap[pwd];}

With Touch ID verification, it needs to be called after the Touch ID verification is successful, and the password corresponding to the Touch ID is used for verification, as follows.

- (SGAccount *)getTouchIDAccount {    NSStringself.accountSet.touchIDPassword;    returnself.accountSet.accountMap[pwd];}
Implementation of window root controller selection

If you already have an account, return the verification controller wrapped by the navigation controller SGWelcomeViewController , if you have not registered an account, first initialize a navigation controller wrapped and SGWelcomeViewController push a registration controller into the view stack SGRegisterViewController , is to ensure that the registration can be returned to the verification controller, and the registration from the verification page entered the same logic, the implementation of the following.

- (UIViewController *)getRootViewController {    if ([self hasAccount]) {        return[[UINavigationController alloc] initWithRootViewController:[SGWelcomeViewController new]];    }    SGWelcomeViewController *welcomeVc = [SGWelcomeViewController new];    SGRegisterViewController *registerVc = [SGRegisterViewController new];    UINavigationController *nav = [UINavigationController new];    nav.viewControllers = @[welcomeVc, registerVc];    return nav;}
Summarize

This paper mainly introduces the interface and implementation of data classes and management classes related to registration and login verification, and in the subsequent registration and login verification view design, only the tool class is required. Welcome to follow the project, the project can be found at the beginning of this article.

iOS open source encrypted album agony implementation (i)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.