From a7469975aded00b32b9a1fde9ad3aa16d998b25c Mon Sep 17 00:00:00 2001 From: Michael Starke Date: Thu, 31 Jan 2019 15:52:50 +0100 Subject: [PATCH] Updated entropy calculation to account for required characters --- MacPass/MPPasswordCreatorViewController.m | 8 +++-- MacPass/NSString+MPPasswordCreation.m | 41 ++++++++++++++++++----- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/MacPass/MPPasswordCreatorViewController.m b/MacPass/MPPasswordCreatorViewController.m index 5c23850e..b68c5ac6 100644 --- a/MacPass/MPPasswordCreatorViewController.m +++ b/MacPass/MPPasswordCreatorViewController.m @@ -175,7 +175,7 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) { length:self.passwordLength]; } -- (NSString*)_customCharacters{ +- (NSString *)_customCharacters{ if(self.useCustomString && self.customCharactersTextField.stringValue.length > 0) { return self.customCharactersTextField.stringValue; } @@ -319,6 +319,7 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) { - (void)controlTextDidChange:(NSNotification *)obj { if([obj object] == self.customCharactersTextField) { self.setDefaultButton.enabled = YES; + [self _resetCharacters]; [self _generatePassword:nil]; } } @@ -394,7 +395,10 @@ typedef NS_ENUM(NSUInteger, MPPasswordRating) { // ensure minimum character lenght if(self.ensureOccurance) { - + NSUInteger minimumLength = [NSString minimumPasswordLengthWithCharacterSet:self.characterFlags customCharacters:[self _customCharacters] ensureOccurance:self.ensureOccurance]; + if(self.passwordLength < minimumLength) { + self.passwordLength = minimumLength; + } } } diff --git a/MacPass/NSString+MPPasswordCreation.m b/MacPass/NSString+MPPasswordCreation.m index 17b96cd7..a834e8e7 100644 --- a/MacPass/NSString+MPPasswordCreation.m +++ b/MacPass/NSString+MPPasswordCreation.m @@ -84,7 +84,7 @@ static NSString *mergeWithoutDuplicates(NSString* baseCharacters, NSString* cust ensureOccurence:(BOOL)ensureOccurence length:(NSUInteger)length { if(ensureOccurence) { - length = MAX(length, [NSString minimumPasswordLengthWithCharacterSet:allowedCharacters customCharacters:customCharacters ensureOccurance:ensureOccurence]); + length = MAX(length, [NSString minimumPasswordLengthWithCharacterSet:allowedCharacters customCharacters:customCharacters ensureOccurance:ensureOccurence]); } NSMutableString *password = [NSMutableString stringWithCapacity:length]; NSString *characters = mergeWithoutDuplicates( @@ -160,16 +160,39 @@ static NSString *mergeWithoutDuplicates(NSString* baseCharacters, NSString* cust - (CGFloat)entropyWhithCharacterSet:(MPPasswordCharacterFlags)characterSet customCharacters:(NSString *)customCharacters ensureOccurance:(BOOL)ensureOccurance { + CGFloat passwordLength = self.composedCharacterLength; + CGFloat entropy = 0; if(ensureOccurance) { - return 0; - } - else { - NSString *characters = nil; - characters = mergeWithoutDuplicates(allowedCharactersString(characterSet), customCharacters); - CGFloat alphabetCount = characters.composedCharacterLength; - CGFloat passwordLength = self.composedCharacterLength; - return passwordLength * ( log10(alphabetCount) / log10(2) ); + CGLError alphabetCount = 0; + if(characterSet & MPPasswordCharactersLowerCase) { + alphabetCount = (CGFloat)characterClassMap()[@(MPPasswordCharactersLowerCase)].length; + entropy += log2(alphabetCount); + } + if(characterSet & MPPasswordCharactersUpperCase) { + alphabetCount = (CGFloat)characterClassMap()[@(MPPasswordCharactersUpperCase)].length; + entropy += log2(alphabetCount); + } + if(characterSet & MPPasswordCharactersNumbers) { + alphabetCount = (CGFloat)characterClassMap()[@(MPPasswordCharactersNumbers)].length; + entropy += log2(alphabetCount); + + } + if(characterSet & MPPasswordCharactersSymbols){ + alphabetCount = (CGFloat)characterClassMap()[@(MPPasswordCharactersSymbols)].length; + entropy += log2(alphabetCount); + + } + if(customCharacters.composedCharacterLength > 0) { + entropy += log2(customCharacters.composedCharacterLength); + } + NSUInteger minLenght = [NSString minimumPasswordLengthWithCharacterSet:characterSet customCharacters:customCharacters ensureOccurance:ensureOccurance]; + passwordLength -= minLenght; } + NSString *characters = mergeWithoutDuplicates(allowedCharactersString(characterSet), customCharacters); + CGFloat alphabetCount = characters.composedCharacterLength; + entropy += passwordLength * log2(alphabetCount); + + return entropy; } - (NSString *)shuffledString {