New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unify password generation across FreeIPA #317
Conversation
|
NACK You replaced os.random() by ipa_generate_password, but ipa_generate password does not generate random bytes but random printable characters (entropy--) so you have to recalculate a new password length accordingly or edit ipa_generate_password function to generate random bytes. Also I noticed you removed base64encoding, are you sure that places where it was used can handle all bytes characters (nonprintable, etc)? I would stay with base64 there. |
|
Please replace this by something sane, security by obscurity worked well in Roman empire, but now please generate directly password with entropy 128bits without using sha1 |
|
The passwords should have around the same entropy now. SHA-1 actually produces 160bit outputs (hence 40-characters long hexadecimal digests), so I recounted it for 20-bytes entropy. As ipa_generate_password creates passwords of only printable characters (and a space) by default, base64 should not be a requirement here. However, a space could be a problem somewhere I guess, should it be removed as well from the defaul behavior of the password generator? |
Sure, my bad As we discussed offline, due NSS FIPS requirements, we should get rid off base64 encoding. I wouldn't remove space from there, can you check if NSS supports it? |
|
NSS does support spaces in its passwords it seems. My hopes are that HTTP will be able to understand spaces in its password.conf file. |
|
Apparently, spaces are ok even in HTTP password.conf so I guess we can leave it there. |
|
@stlaz SHA-1 DOES NOT add entropy at all, you need the right number of bits in INPUT for whatever trasformation you use. |
|
Please don't use a hack like sha1() to turn a random byte sequence into a hex value. At best sha1 keeps the entropy of the input. I also don't like the fact that the function only cares about the length of the output. The actual length is irrelevant. We care about the entropy of the output. Let's drop pwd_len and apply proper math instead: |
|
@simo5 I was actually trying to get rid of SHA-1 and I am aware that entropy will not be raised, that part of the code draw a smile on some of our faces here, really :) |
| f = os.open(pwd_file, os.O_CREAT | os.O_RDWR) | ||
| os.write(f, hex_str) | ||
| os.write(f, password) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's with this ugly code? Why does it use a file descriptor instead of a proper file and context manager?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really sure.
|
We may need a max length argument if we are dealing with some stuff that has issues with more then max length caracters ... In that case we can warn (or raise, we'll have to decide) not enough entropy will be available is max length is not sufficient to hold the desired entropy. |
|
@stlaz Your patch looks good. My comment regarding SHA1 was aimed at comment #317 (comment) . The suggestion of SHA1 is a Verschlimmbesserung (improvement for the worse) of the current code. I studied the implementation |
|
@tiran @simo5 If you read my comments properly I was happy with removing sha1() and I pointed out that ipa_generate_password() must generate entropy 160bits as was probably originally aimed by using sha1() @simo5 I'm fine with removing space then @simo5 Standa found out that when FIPS is enabled NSS is not willing to accept some password, it requires some special chars AFAIK @stlaz knows details @tiran I'm afraid we need to keep special chracters there as I mentioned above ^ @tiran thank you for nice code snippet @tiran AFAIK you misunderstood my comment, I wanted to "replace sha1 with something sane" or I don't understand what is wrong with my comment. |
|
@mbasti-rh I probably misunderstood your intention. I read your comment as "Replace it with something sane, the sane thing is sha1". By the way I'm currently tangled up in a twitter discussion about Python's new secrets module and entropy. The module doc has a nice recipe to generate passwords with special properties https://docs.python.org/3.6/library/secrets.html#recipes-and-best-practices . I asked a friend of mine and real (tm) cryptographer about entropy for black box tokens. He told me
|
|
|
@tiran IMO you need check |
|
@mbasti-rh |
|
@tiran True, I would like to have there at least assert witch prevents devs to use more than let say 15% per class and more than 50% together, to prevent silly mistakes. It will also reduces possibility of starvation when too many passwords don't match requirements Do you want to send this as PR or are you fine by adding it to this PR by Standa? |
|
Guys, I'm confused. What exactly is the purpose of If we are clever enough we can get away with the |
|
It generates random tokens than can be used as:
It is written in class docstring Yes we can randomly generate strings for each class with specified length, then generate randomly the rest, and finally make order of characters random. However I'm not sure if this is from crypto point of view equal to generate random string at once and then check validity, there can be something we don't see, but probably not. |
|
@mbasti-rh You are missing the point and thus do not answer my question: The docstring does not tell anything about relation of 'entropy' and the output. What is the relation? Does it assume that attacker knows init parameters of TokenGenerator? Or not? How can we do analysis without knowing threat model first? Does I would argue that for any IPA-internal passwords we must assume that attacker knows the input parameters because he can easily read the source code. |
|
Correct me if I'm wrong here but I believe we're going for the scenario where the attacker has to guess the
From the code you can see that if a certain class of characters should not be used, it's not accounted for in the calculation of the final length of the password but that's about it - if a further restriction is made (>1 character of the give character class), this restriction is also not accounted for. But since we're the ones who'll be using this token generator, I think we could live with this. There should be a warning in a docstring somewhere, though. edit: Just realized - the code is wrong, the restriction to a certain class == None should just mean that the characters from the given class could but don't have to appear in the password (thus still need to be accounted for), the restriction of a certain class == 0 should mean the character should not appear in the password and should not be accounted for in the length calculation. |
|
The main problem here is that we are mixing two approaches together, i.e. entropy specification using bits + specification using character classes etc. which used to be means of expressing entropy requirements in a way understandable by ordinary users. If I understand it correctly, the encoding here is just to please password-quality checkers because the real password strength should be provided by the So I propose to use character classes only for encoding but not during generation. That should simplify the code and make it easier to understand. |
|
Talk is cheap so here is the code! This code deterministically generates passwords. If character constraints are specified, the code might generate slightly longer passwords than the brute-force method. For example, 256 bit password with FIPS-compliant constrains (3 character classes) the difference is 41 vs. 40 characters. Given this different, I think that determinism trumphs shorter passwords. Also, I think that it does not make sense to have |
428a158
to
17b08d5
Compare
|
Works for me, server installation including DNSSEC worked fine. |
|
I would like to review this as well, so removing ACK to prevent pushing this to master |
|
PR needs rebase |
Also had to recalculate entropy of the passwords as originally, probability of generating each character was 1/256, however the default probability of each character in the ipa_generate_password is 1/95 (1/94 for first and last character). https://fedorahosted.org/freeipa/ticket/5695
A change to the algorithm that generates random passwords for multiple purposes throught IPA. This spells out the need to assess password strength by the entropy it contains rather than its length. This new password generation should also be compatible with the NSS implementation of password requirements in FIPS environment so that newly created databases won't fail with wrong authentication. https://fedorahosted.org/freeipa/ticket/5695
|
I don't see any merge conflicts and the rebase was automatic so I don't see why, but ok. Just note that ipatool may be confused with me commiting @pspacek's commit as he was the author of the main code and I put it to work with the rest of IPA. |
When installing FreeIPA in FIPS mode I noticed that there were often different ways of generating passwords in different spots raising the same issue with password requirements. Handling password generation at one centralized spot should allow us handle any password requirements issues at this very spot.