From b2f3cc690391864b1fe63ce4c1391d9be6fc5e3e Mon Sep 17 00:00:00 2001 From: TheZ3ro Date: Thu, 24 Nov 2016 03:59:24 +0100 Subject: Add some password-related feature (#92) * Add Standalone Password Generator. Closes #18 * Add an entropy meter for passwords. Closes #84 * Don't require password repeat when it is visible. Fixes #27 --- utils/CMakeLists.txt | 4 ++ utils/entropy-meter.cpp | 116 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 utils/entropy-meter.cpp (limited to 'utils') diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt index 7512c607e..d0cfb5a31 100644 --- a/utils/CMakeLists.txt +++ b/utils/CMakeLists.txt @@ -24,3 +24,7 @@ target_link_libraries(kdbx-extract Qt5::Widgets ${GCRYPT_LIBRARIES} ${ZLIB_LIBRARIES}) + + +add_executable(entropy-meter entropy-meter.cpp) +target_link_libraries(entropy-meter zxcvbn) diff --git a/utils/entropy-meter.cpp b/utils/entropy-meter.cpp new file mode 100644 index 000000000..3266ec55b --- /dev/null +++ b/utils/entropy-meter.cpp @@ -0,0 +1,116 @@ +/* +Part of this code come from zxcvbn-c example. +Copyright (c) 2015, Tony Evans +Copyright (c) 2016, KeePassXC Team + +See zxcvbn/zxcvbn.cpp for complete COPYRIGHT Notice +*/ + +#include +#include +#include +#include "zxcvbn/zxcvbn.h" + +/* For pre-compiled headers under windows */ +#ifdef _WIN32 +#include "stdafx.h" +#endif + +static void calculate(const char *pwd, int advanced) +{ + double e; + int len = strlen(pwd); + if (advanced == 0){ + e = ZxcvbnMatch(pwd, 0, 0); + printf("Pass '%s' \tLength %d\tEntropy %.3f\tLog10 %.3f\n", pwd, len, e, e * 0.301029996); + } else { + int ChkLen; + ZxcMatch_t *info, *p; + double m = 0.0; + e = ZxcvbnMatch(pwd, 0, &info); + for(p = info; p; p = p->Next) { + m += p->Entrpy; + } + m = e - m; + printf("Pass '%s' \tLength %d\tEntropy %.3f\tLog10 %.3f\n Multi-word extra bits %.1f\n", pwd, len, e, e * 0.301029996, m); + p = info; + ChkLen = 0; + while(p) { + int n; + switch(static_cast(p->Type)) + { + case BRUTE_MATCH: printf(" Type: Bruteforce "); break; + case DICTIONARY_MATCH: printf(" Type: Dictionary "); break; + case DICT_LEET_MATCH: printf(" Type: Dict+Leet "); break; + case USER_MATCH: printf(" Type: User Words "); break; + case USER_LEET_MATCH: printf(" Type: User+Leet "); break; + case REPEATS_MATCH: printf(" Type: Repeated "); break; + case SEQUENCE_MATCH: printf(" Type: Sequence "); break; + case SPATIAL_MATCH: printf(" Type: Spatial "); break; + case DATE_MATCH: printf(" Type: Date "); break; + case BRUTE_MATCH+MULTIPLE_MATCH: printf(" Type: Bruteforce(Rep)"); break; + case DICTIONARY_MATCH+MULTIPLE_MATCH: printf(" Type: Dictionary(Rep)"); break; + case DICT_LEET_MATCH+MULTIPLE_MATCH: printf(" Type: Dict+Leet(Rep) "); break; + case USER_MATCH+MULTIPLE_MATCH: printf(" Type: User Words(Rep)"); break; + case USER_LEET_MATCH+MULTIPLE_MATCH: printf(" Type: User+Leet(Rep) "); break; + case REPEATS_MATCH+MULTIPLE_MATCH: printf(" Type: Repeated(Rep) "); break; + case SEQUENCE_MATCH+MULTIPLE_MATCH: printf(" Type: Sequence(Rep) "); break; + case SPATIAL_MATCH+MULTIPLE_MATCH: printf(" Type: Spatial(Rep) "); break; + case DATE_MATCH+MULTIPLE_MATCH: printf(" Type: Date(Rep) "); break; + + default: printf(" Type: Unknown%d ", p->Type); break; + } + ChkLen += p->Length; + printf(" Length %d Entropy %6.3f (%.2f) ", p->Length, p->Entrpy, p->Entrpy * 0.301029996); + for(n = 0; n < p->Length; ++n, ++pwd) { + printf("%c", *pwd); + } + printf("\n"); + p = p->Next; + } + ZxcvbnFreeInfo(info); + if (ChkLen != len) + printf("*** Password length (%d) != sum of length of parts (%d) ***\n", len, ChkLen); + } +} + +int main(int argc, char **argv) +{ + printf("KeePassXC Entropy Meter, based on zxcvbn-c.\nEnter your password below or pass it as argv\n"); + printf(" Usage: entropy-meter [-a] [pwd1 pwd2 ...]\n> "); + int i, advanced; + if ((argc > 1) && (argv[1][0] == '-') && (!strcmp(argv[1], "-a"))) + { + advanced = 1; + } + i = 2; + if (i >= argc) + { + /* No test passwords on command line, so get them from stdin */ + char line[500]; + while(fgets(line, sizeof line, stdin)) + { + /* Drop the trailing newline character */ + for(i = 0; i < static_cast(sizeof line - 1); ++i) + { + if (line[i] < ' ') + { + line[i] = 0; + break; + } + } + if (line[0]) + calculate(line,advanced); + printf("> "); + } + } + else + { + /* Do the test passwords on the command line */ + for(; i < argc; ++i) + { + calculate(argv[i],advanced); + } + } + return 0; +} -- cgit v1.2.3