Re: Password strengh meter in KNewPasswordDialog

2013-04-10 Thread Luigi Toscano
On Thursday 04 of April 2013 11:52:09 Martin Sandsmark wrote:
> On Thu, Apr 04, 2013 at 01:02:21AM +0200, Luigi Toscano wrote:
> > Have you seen this?
> > https://fedorahosted.org/libpwquality/
> > https://fedoraproject.org/wiki/Features/PasswordQualityChecking
> 
> It doesn't contain any docs about how it calculates anything that I can
> find, which is a bit worrying. From looking at the code it looks very
> simplistic.

Some answers from the author (now in CC:):
 The algorithms for checking the password parameters are simple because 
the definition of the parameters is simple - the code is partially reused from 
pam_cracklib. The scoring algorithm (which is not too important) is arbitrary 
and created by adjusting outputs that were calculated by it on a small 
password dictionary.
 does it mean that the main focus is the checking the password 
parameters, and that the scoring algorithm can be replaced? Or did I miss all 
the points? :)
 The algorithm that generates the password is trying to create 
pronounceable password with defined entropy.
 Yes.
 Yes to the first question actually :)
 so, given the focus of the feature discussed (scoring the password), 
is it correct that the library is not the proper tool?
 Is the strength meter purpose to be used for system passwords?
 If so the libpwquality should be used because it will honor the system 
wide settings enforced by the PAM configuration (at least on Fedora it is so)
 the change would be in KNewPasswordDialog, which is part of KDELibs 
and used in many applications whenever a password is needed
 (or it should be used :)
[15:32:44]  ok, then using libpwquality might be slightly more 
complicated as the applications should be able to set their own preferences 
for minimum password parameters
 I see
 can I copy & paste this entire conversation?
 (which is of course possible with libpwquality, but I suppose the 
KNewPasswordDialog API doesn't allow this)
 sure

Ciao
-- 
Luigi


Re: Password strengh meter in KNewPasswordDialog

2013-04-04 Thread Martin Sandsmark
On Thu, Apr 04, 2013 at 01:02:21AM +0200, Luigi Toscano wrote:
> Have you seen this?
> https://fedorahosted.org/libpwquality/
> https://fedoraproject.org/wiki/Features/PasswordQualityChecking

It doesn't contain any docs about how it calculates anything that I can find,
which is a bit worrying. From looking at the code it looks very simplistic.

But why not simply use cracklib?

Or you could try to compress the string with qCompress/zlib to find a measure
of the entropy contained?

-- 
Martin Sandsmark


Re: Password strengh meter in KNewPasswordDialog

2013-04-04 Thread Christoph Feck
On Thursday 04 April 2013 00:53:28 Rolf Eike Beer wrote:
> Am Mittwoch 03 April 2013, 14:53:40 schrieb Thiago Macieira:
> > On quarta-feira, 3 de abril de 2013 22.39.47, Rolf Eike Beer 
wrote:
> > > Also punish all passwords harder
> > > that do not contain all types of characters, so a password
> > > containing only lowercase characters and numbers needs to be
> > > much longer than one also containing specials and uppercase
> > > characters.
> > 
> > You do realise that a password isn't truly random if it has to
> > contain all types? I hate when I'm forced to do that.
> > 
> > For example, here are 10 password generated with keepassx with
> > Upper, lower, numbers, minus, underline, and special characters:
> > 
> > Note how there a few without digits. But since they're all
> > randomly-generated using the same method, they all have the same
> > probability.
> > 
> > For custom
> > 
"!@#$%^&*abcdefghijklmnopqrstuvxwyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123
> > 456789", I get:
> > 
> > Out of ten, only three got all four types of characters. All
> > *ten* got a score lower than 75, which is your threshold for the
> > green colour.
> 
> There are 5 types of characters (also in the old algorithm):
> Uppercase, lowercase vowel, lowercase consonant, digits, and
> specials. You are right, and indeed there are 2 changes to the
> algorith that I do: penalize sequences and penalize too few types.
> Especially the later part may need some tweaks. From my point of
> view there is no need to divide lowercase characters in 2 classes,
> in an earlier version of my patch I even removed this.

The distinction between vowels and consonants has been added to try to 
detect normal words. The password "kgnlhtbm" should have a higher 
score compared to "pibatero". In the latter, the changes between 
vowels and consonants make it look like a word (even it isn't, at 
least not in any language I know).

> 
> > I generated 100 10-character passwords by base64 encoding
> > /dev/urandom. With the old algorithm, 65% of the passwords were
> > 100 points, 20% more between 90 and 99 and 10% between 80 and
> > 89. With the new algorithm, only 14 passwords got 100 points,
> > 21% are between 80 and 99 and 40% of them are between 70 and 79
> > points. There was even one entry that got 30 points.
> > 
> > I have to increase the password length to 14 characters to 65% of
> > 100 points. And they're all random.
> 
> I have changed my algorithm in some ways and rechecked: removed
> vowel class, divide by one less than we have character classes,
> and both. Then your random passwords give better results with the
> new algorithm, sometimes even better than with the old one. There
> are a few exceptions (qbF\FdHCy, U2WVF9kLH) that still score worse
> with the new algorithm. One of them has no digit, the other no
> special, so I am not surprised as there are very few transitions
> between character classes in them.
> 
> So, yes, you are absolutely right. Suggestions about how to improve
> that absolutely welcome.
> 
> Eike

Christoph Feck (kdepepo)
KDE Quality Team


Re: Password strengh meter in KNewPasswordDialog

2013-04-03 Thread Michael Pyne
On Wednesday, April 03, 2013 18:47:17 Cristian Tibirna wrote:
> On Wednesday 03 April 2013 22:39:47 Rolf Eike Beer wrote:
> > Hi all,
> 
> http://xkcd.com/936/

In fairness, common dictionary words (no matter how long) have less entropy 
than you would get just from adding the letters. Each word can simply be 
considered a letter in a larger alphabet. E.g. a 4-word "long" password from 
within the 500 most common words is one of only 6.25e10 possibilities.

So I'd use dictionary words as a supplement to other means, not by itself. The 
authors of JohnTheRipper surely read XKCD just as we do. :)

> > so a password
> > containing only lowercase characters and numbers needs to be much longer
> > than one also containing specials and uppercase characters.
> 
> Really, this whole "can be short because has mixed types of characters"
> nonsense has to die.
> 
> There is a math theory behind password strength. There might even be
> libraries capable of measuring this properly.

Completely agreed. If anything it seems that even the idea of "password 
entropy" might not apply to any passwords that a human generates [1]. In such 
a scenario it may be best to simply correlate "password strength" loosely with 
"password length".

[1] 
http://reusablesec.blogspot.com/2010/10/new-paper-on-password-security-metrics.html

Regards,
 - Michael Pyne

signature.asc
Description: This is a digitally signed message part.


Re: Password strengh meter in KNewPasswordDialog

2013-04-03 Thread Luigi Toscano
Rolf Eike Beer wrote:

> So, yes, you are absolutely right. Suggestions about how to improve that 
> absolutely welcome.

Have you seen this?

https://fedorahosted.org/libpwquality/
https://fedoraproject.org/wiki/Features/PasswordQualityChecking

Ciao
-- 
Luigi





Re: Password strengh meter in KNewPasswordDialog

2013-04-03 Thread Rolf Eike Beer
Am Mittwoch 03 April 2013, 18:47:17 schrieb Cristian Tibirna:
> On Wednesday 03 April 2013 22:39:47 Rolf Eike Beer wrote:
> > Hi all,
> > 
> > the current issue of (German) Linux Magazin has an article comparing some
> > GnuPG frontends. One issue discussed there is the "password strength
> > meter"
> > that gives e.g. 25% strength indication for things like 123456789. I don't
> > know about Kleopatra, but KGpg uses KNewPasswordDialog and it's strength
> > meter for this. I propose to change the algorithm used to calculate the
> > password strength to remove key sequences from the "length" calculation of
> > the password, i.e. 123 has the same length as 1. Also punish all passwords
> > harder that do not contain all types of characters,
> 
> http://xkcd.com/936/
> 
> > so a password
> > containing only lowercase characters and numbers needs to be much longer
> > than one also containing specials and uppercase characters.
> 
> Really, this whole "can be short because has mixed types of characters"
> nonsense has to die.

Not short, just shorter. So this boils down to the question: how can we count 
the bits of entropy?

> There is a math theory behind password strength. There might even be
> libraries capable of measuring this properly.
> 
> IMH (non-contributor) O, we should try to reuse here.

Adding dependencies would only affect 4.11, but I guess even for that the time 
may already be too short. Not that it wouldn't be a good idea for 4.12 if it's 
worth the effort.

Eike

signature.asc
Description: This is a digitally signed message part.


Re: Password strengh meter in KNewPasswordDialog

2013-04-03 Thread Rolf Eike Beer
Am Mittwoch 03 April 2013, 14:53:40 schrieb Thiago Macieira:
> On quarta-feira, 3 de abril de 2013 22.39.47, Rolf Eike Beer wrote:
> > Also punish all passwords harder
> > that do not contain all types of characters, so a password containing only
> > lowercase characters and numbers needs to be much longer than one also
> > containing specials and uppercase characters.
> 
> You do realise that a password isn't truly random if it has to contain all
> types? I hate when I'm forced to do that.
> 
> For example, here are 10 password generated with keepassx with Upper, lower,
> numbers, minus, underline, and special characters:
> 
> Note how there a few without digits. But since they're all
> randomly-generated using the same method, they all have the same
> probability.
> 
> For custom
> "!@#$%^&*abcdefghijklmnopqrstuvxwyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", I
> get:
> 
> Out of ten, only three got all four types of characters. All *ten* got a
> score lower than 75, which is your threshold for the green colour.

There are 5 types of characters (also in the old algorithm): Uppercase, 
lowercase vowel, lowercase consonant, digits, and specials. You are right, and 
indeed there are 2 changes to the algorith that I do: penalize sequences and 
penalize too few types. Especially the later part may need some tweaks. From 
my point of view there is no need to divide lowercase characters in 2 classes, 
in an earlier version of my patch I even removed this.

> I generated 100 10-character passwords by base64 encoding /dev/urandom. With
> the old algorithm, 65% of the passwords were 100 points, 20% more between
> 90 and 99 and 10% between 80 and 89. With the new algorithm, only 14
> passwords got 100 points, 21% are between 80 and 99 and 40% of them are
> between 70 and 79 points. There was even one entry that got 30 points.
> 
> I have to increase the password length to 14 characters to 65% of 100
> points. And they're all random.

I have changed my algorithm in some ways and rechecked: removed vowel class, 
divide by one less than we have character classes, and both. Then your random 
passwords give better results with the new algorithm, sometimes even better 
than with the old one. There are a few exceptions (qbF\FdHCy, U2WVF9kLH) that 
still score worse with the new algorithm. One of them has no digit, the other 
no special, so I am not surprised as there are very few transitions between 
character classes in them.

So, yes, you are absolutely right. Suggestions about how to improve that 
absolutely welcome.

Eike

signature.asc
Description: This is a digitally signed message part.


Re: Password strengh meter in KNewPasswordDialog

2013-04-03 Thread Cristian Tibirna
On Wednesday 03 April 2013 22:39:47 Rolf Eike Beer wrote:
> Hi all,
> 
> the current issue of (German) Linux Magazin has an article comparing some
> GnuPG frontends. One issue discussed there is the "password strength meter"
> that gives e.g. 25% strength indication for things like 123456789. I don't
> know about Kleopatra, but KGpg uses KNewPasswordDialog and it's strength
> meter for this. I propose to change the algorithm used to calculate the
> password strength to remove key sequences from the "length" calculation of
> the password, i.e. 123 has the same length as 1. Also punish all passwords
> harder that do not contain all types of characters, 

http://xkcd.com/936/

> so a password
> containing only lowercase characters and numbers needs to be much longer
> than one also containing specials and uppercase characters.

Really, this whole "can be short because has mixed types of characters" 
nonsense has to die.

There is a math theory behind password strength. There might even be libraries 
capable of measuring this properly. 

IMH (non-contributor) O, we should try to reuse here.

-- 
Cristian Tibirna
KDE developer .. tibi...@kde.org .. http://www.kde.org


signature.asc
Description: This is a digitally signed message part.


Re: Password strengh meter in KNewPasswordDialog

2013-04-03 Thread Thiago Macieira
On quarta-feira, 3 de abril de 2013 22.39.47, Rolf Eike Beer wrote:
> Also punish all passwords harder 
> that do not contain all types of characters, so a password containing only 
> lowercase characters and numbers needs to be much longer than one also 
> containing specials and uppercase characters.

You do realise that a password isn't truly random if it has to contain all 
types? I hate when I'm forced to do that.

For example, here are 10 password generated with keepassx with Upper, lower, 
numbers, minus, underline, and special characters:

old / new
"d3(;$puO   82  82
S+157jz"9   92  72
4Q%p6sZwo   100 100
0We|va}!G   92  92
*+"$ZIf6p   72  62

'HC4@xiH?   82  80
qbF\FdHCy   82  52
'$Y(7sy8<   100 82
)Nxrml@u[   100 90
U-+*al`S)   82  62

Note how there a few without digits. But since they're all randomly-generated 
using the same method, they all have the same probability.

For custom 
"!@#$%^&*abcdefghijklmnopqrstuvxwyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", I 
get:

4xy1pIrwy   100 60
rv8AaI6G8   92  70
YHbcA5C38   92  60
h@abfjih6   72  55
m!58L!TOD   52  42

GNxzg&Rxz   82  52
SFZN5$k@m   82  62
7bmDx@*SW   82  72
U2WVF9kLH   82  47
tgD4cYGjo   82  62

Out of ten, only three got all four types of characters. All *ten* got a score 
lower than 75, which is your threshold for the green colour.

I generated 100 10-character passwords by base64 encoding /dev/urandom. With 
the old algorithm, 65% of the passwords were 100 points, 20% more between 90 
and 99 and 10% between 80 and 89. With the new algorithm, only 14 passwords 
got 100 points, 21% are between 80 and 99 and 40% of them are between 70 and 
79 points. There was even one entry that got 30 points.

I have to increase the password length to 14 characters to 65% of 100 points. 
And they're all random.

-- 
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel Open Source Technology Center
  PGP/GPG: 0x6EF45358; fingerprint:
  E067 918B B660 DBD1 105C  966C 33F5 F005 6EF4 5358


signature.asc
Description: This is a digitally signed message part.


Password strengh meter in KNewPasswordDialog

2013-04-03 Thread Rolf Eike Beer
Hi all,

the current issue of (German) Linux Magazin has an article comparing some 
GnuPG frontends. One issue discussed there is the "password strength meter" 
that gives e.g. 25% strength indication for things like 123456789. I don't 
know about Kleopatra, but KGpg uses KNewPasswordDialog and it's strength meter 
for this. I propose to change the algorithm used to calculate the password 
strength to remove key sequences from the "length" calculation of the 
password, i.e. 123 has the same length as 1. Also punish all passwords harder 
that do not contain all types of characters, so a password containing only 
lowercase characters and numbers needs to be much longer than one also 
containing specials and uppercase characters.

I've attached my strength test program containing both the old and the 
proposed new version of the code. I've tested the new version in 2 variants, 
once with and without the call to toLower() before checking for sequences. 
These are some test passwords I used, mostly some examples of "simple" 
passwords users will use. The last one is a scrambled version of a password I 
saw used somewhere (i.e. every letter replaced with something from the same 
character class to retain the score) that was not totally obvious.

 old nEw new
abcdef45  12  12
abcdefghi 72  22  22
1 12   1   1
1215   2   2
123   17   2   2
1234  20   2   2
12345 22   2   2
12345625   2   2
123456789 32   2   2
qwertz45  25  25
1234test  40  20  20
test1234  30  10  10
a1b2c3d4 100  60  60
a1b2c3d4e5   100  85  85
a1b2c3d4e5f6 100 100 100
a1a1a1a1  40  20  20
  30   2   2
KKvfnDd.  90  57  55

Also I propose to change the color of the strength indicator to red below 50% 
and to yellow below 75%. Since this does not affect any strings and improves 
security I would also push this into 4.10 in noone objects.

Comments?

Eike#include 
#include 

const int reasonablePasswordLength = 8;

int effectivePasswordLength(const QString &password)
{
	enum Category {
		Digit,
		Upper,
		Vowel,
		Consonant,
		Special
	};
	
	Category previousCategory = Vowel;
	QString vowels("aeiou");
	int count = 0;
	int catCount = 0;
	unsigned int catMask = 0;
	
	for (int i = 0; i < password.length(); ++i) {
		QChar currentChar = password.at(i);
		if (!password.left(i).contains(currentChar)) {
			Category currentCategory;
			switch (currentChar.category()) {
case QChar::Letter_Uppercase:
	currentCategory = Upper;
	break;
case QChar::Letter_Lowercase:
	if (vowels.contains(currentChar)) {
		currentCategory = Vowel;
	} else {
		currentCategory = Consonant;
	}
	break;
case QChar::Number_DecimalDigit:
	currentCategory = Digit;
	break;
default:
	currentCategory = Special;
	break;
			}
			switch (currentCategory) {
case Vowel:
	if (previousCategory != Consonant) {
		++count;
	}
	break;
case Consonant:
	if (previousCategory != Vowel) {
		++count;
	}
	break;
default:
	if (previousCategory != currentCategory) {
		++count;
	}
	break;
			}
			previousCategory = currentCategory;
			if (!(catMask & (1 << currentCategory))) {
++catCount;
catMask |= (1 << currentCategory);
			}
		}
	}
	// passwords that have many category changes but few categories are weaker
	return (count * catCount) / 5;
}

int passwordStrength(const QString &password)
{
	QString sPass = password.simplified().toLower();
	
	if (sPass.length() < 2)
		return sPass.length();
	
	int i = 0;
	while (i < sPass.length()) {
		// duplicate characters do not improve the length
		if (sPass[i] == sPass[i + 1]) {
			sPass.remove(i + 1, 1);
			continue;
		}

		// the sequence detection is only reliable in the ASCII range
		if (!sPass[i].isLetterOrNumber()) {
			++i;
			continue;
		}
		
		if (sPass[i].unicode() == sPass[i + 1].unicode() + 1 || sPass[i].unicode() == sPass[i + 1].unicode() - 1) {
			// Remove the old one here. Otherwise we would not catch 123 as a sequence
			sPass.remove(i, 1);
			continue;
		}
		++i;
	}
	
	int pwstrength = (20 * sPass.length() + 80 * effectivePasswordLength(password)) / qMax(reasonablePasswordLength, 2);
	if (pwstrength < 0) {
		pwstrength = 0;
	} else if (pwstrength > 100) {
		pwstrength = 100;
	}
	
	return pwstrength;
}

int old_effectivePasswordLength(const QString &password)
{
	enum Category {
		Digit,
		Upper,
		Vowel,
		Consonant,
		Special
	};
	
	Category previousCategory = Vowel;
	QString vowels("aeiou");
	int count = 0;
	
	for (int i = 0; i < password.length(); ++i) {
		QChar currentChar = password.at(i);
		if (!password.left(i).contains(currentChar)) {
			Category currentCategory;
			switch (currentChar.category()) {
case QChar::Letter_Uppercase:
	currentCategory = Upper;
	break;
case QChar::Letter_Lowercase:
	if (vowels.contains(currentChar)) {
		currentCategory = Vowel;
	} else {