16

This is coming from a joke originally in French:

Enter your password.

carrot

Sorry, your password must be more than 8 characters.

carottegéante
(giant carrot)

Sorry, your password must contain a number

1carottegéante
(1 giant carrot)

Sorry, your password must not contain accented characters

50putaindecarottesgeantes
(50 damn giant carrots)

Sorry, your password must contain at least one capital letter

50PUTAINdecarottesgeantes
(50 DAMN giant carrots)

Sorry, your password must not contain two consecutive capital letters

5OPutainDeCarottesGeantesQueJeVaisTeMettreAuCulSiTuNeMedonnesPasImmediatementUnAcces!
(50 Damn Giant Carrots That I Will Put In Your Ass If You Do Not Immediately Give Me Access!)

Sorry, your password must not contain punctuation characters

AttentionMaintenantJeVaisAllerTeTrouverEtTeMettreVraimentLes50CarottesGeantesSiTuContinues (Caution Now, I'll Go Find You And Really Put 50 Giant Carrots If This Continues)

Sorry, this password is already in use.

But speaking around with a friend:

  • I said:

    This is a built joke only: there is a typo on 3th answer: ne soit pas.. and at all, I don't know any user creation engine that do check for already used passwords.

  • My friend answer:

    You're right, it's a joke, but you could configure PAM to do such a check:
    password required pam_pwcheck.so nullok remember=N

Well, I don't understand!

Any unauthorized person could check if a password is used by simply create a new (fake) account!

What could be the goal of this kind of check?

Xander
  • 35,616
  • 27
  • 114
  • 141
  • A translation might be in order here. Can't help you without it. –  Jan 19 '14 at 13:09
  • Funny joke, but french... sorry! – F. Hauri - Give Up GitHub Jan 19 '14 at 13:12
  • 1
    Right, which you could easily translate to English for other users to give input. At this point, I don't have a clue what you're asking. You keep saying it's a joke as well, which makes me wonder if this is even a legitimate question. Are you waiting for a French speaking individual to help you? If so, I think that the question would be unsuitable since you're restricting access to the information within this thread to specific people. The text isn't even selectable, it's an image, so using translation tools isn't even possible. –  Jan 19 '14 at 13:15
  • 1
    Well, the joke is about how password systems tend to work more than they are about how they should work; the refusal to diacritics is another case where many existing systems pointlessly reduce security and of course more annoying to those who use languages with heavy use of diacritics (like French) than those where they are rare (like English). Refusal to accept spaces is a related common flaw, though not as annoying as accepting them on setting and refusing them on actual password input. – Jon Hanna Jan 19 '14 at 15:31
  • 1
    Best English language version of this joke I've seen: https://fbcdn-sphotos-g-a.akamaihd.net/hphotos-ak-prn2/t1/1555314_218074788377092_1881157452_n.jpg – Ladadadada Jan 19 '14 at 16:02
  • @Ladadadada lol, they took the same approach to replacing the stupid refusal of a diacritic with a stupid refusal of a space that I suggest in my answer. – Jon Hanna Jan 19 '14 at 16:12

3 Answers3

26

You misunderstand what remember does for pam_pwcheck; see the man page:

remember=XX

Remember the last XX passwords and do not allow the user to reuse any of these for the next XX password changes. XX is a number between 1 and 400.

With this option, pam_pwcheck will reject attempts at reusing a password which was previously used by the same user. It does not do anything cross-users; it will not warn you about whether your password of choice is used by anybody else or not.

In fact, such a check would be expensive to implement if proper password hashing is in place (with salts and many iterations for slowness, it would take several minutes to "try" the putative password for thousands of other users). As you say, warning users about how a potential password is already used by another user would be, by itself, a serious security issue; but it would also mean that the passwords are not stored properly, and that is another serious security issue.

Thomas Pornin
  • 322,884
  • 58
  • 787
  • 955
6

pam_pwcheck only remembers passwords for a given user, as the other answer says.

The other part of the question is, "What could be the goal of this kind of check?"

There are indeed systems that do checks of all existing passwords. Generally such systems are either storing passwords in plaintext, or an un-salted hash that doesn't depend upon the username or anything else that would prevent a match being quickly found. I've come across this as a user, as a functionality request (which I have refused as impossible to do with any reasonable means of storing the password, along with being inherently flawed as per below) or as an objection to fixing the use of plaintext storage.

And the goal is two-fold:

  1. Since passwords should be hard to guess, the ideal would be if they were close to random in terms of unpredictability (the problem of remembering the password is another matter*, and one often forgotten when people develop a new enthusiasm for password strength). Since intuitively, random means there is little in the way of repetition (something anyone here will likely know is a fallacy but certainly a fallacy that is held), then repetition is hence a bad sign.

  2. More reasonably, if someone else is using the password, it likely is a weak password that we couldn't detect (e.g. using details of a company office like the phone number to create the password in a way that another employee might try but otherwise passes strength tests), that could be guessed, as essentially the user has indeed just guessed it.

The flaws with the first thought is the flaw of not understanding repetition in randomness, and with expecting perfectly random password unless backed up with a policy that allows hard-to-remember password to be securely remembered.

The flaws with the second thought are:

  1. We need to store password relatively insecurely in order to make the check in the first place.
  2. We've just leaked a password to someone.
  3. We've likely identified a weak password, but not warned the person actually using it.

But still, those flaws don't mean it doesn't happen. There is after all another flaw in the system in the joke; refusing carottegéante because of the diacritic. There are technical reasons to refuse diacritics in various places (though unless you're having to interoperate with other people's code, those reasons are utterly inexcusable in modern code), but I've rather bizarrely seen it refused by systems that would accept diacritics in usernames! Likewise many systems refuse spaces in passwords, and so on. Generally, I'd put this down to cargo-cult programming; someone else did it, so you copy it. To a degree this isn't entirely unreasonable; I certainly copy what those that know better than me do when it comes to security, so I wouldn't entirely blame someone for blindly copying such policies. Still, it takes only a short pause to realise that there's no way that accepting "jdiwmfojkslofklo" but not accepting "ﬤסּוּﭞﻘﺪӐӓҾӌȕ" improves anything, and indeed it reduces the range of possible passwords to attack.

Anyway, the rule some systems have against spaces gives us an approach to translating the joke into English; make the second password attempt "giant carrots" with a space.

*That's what post-it notes are for, isn't it?

Jon Hanna
  • 279
  • 1
  • 5
  • I think the issue with non-ASCII characters is that they may have more than one representation, and the rules for which sequences of code points are equivalent are not constant. If canonical representations change, usernames and other clear-text data can be updated; hashed passwords cannot. If, hypothetically, Unicode were to in one year define a combining diacritic for Q with an acute accent, and in a later year define a code point for a Q-with-acute character, it may be difficult for a server to recognize them as equivalent (the only way it could would be to automatically... – supercat Jan 19 '14 at 17:32
  • ...have every attempted login attempt aautomatically try all representations of all characters in the password for which multiple representations exist--not pretty.) – supercat Jan 19 '14 at 17:33
  • 1
    @supercat If Unicode added such a composed character, the composition would be an excluded composition for NFC. – Jon Hanna Jan 19 '14 at 18:43
  • A typed-in password will go through various parts of a system (keyboard driver, GUI handlers, password-field handling code, etc.) that may have varying knowledge regarding Unicode and the latest changes. If one version of a client computer's GUI handler returns an incorrectly-normalized string and the database software at the time doesn't recognize that the string isn't normalized correctly, how can one avoid or resolve the troubles that would result if the GUI handler is updated to fix the bug? One might hope such things wouldn't happen, but is all Unicode-handling code correct and bug-free? – supercat Jan 19 '14 at 23:28
  • @supercat Hash(NFC(string)). Problem solved. Also, U+0020 is normalised to U+0020 in all normalisation forms; justify banning that. – Jon Hanna Jan 20 '14 at 00:30
  • Where would the NFC operation be performed? When the keyboard-driving code relays character codes to the GUI password-entry widget, it's not going to know whether they're going to be wanted as combined or uncombined form. If a keyboard driver outputs a code which didn't exist when any of the downstream code was written, and a later version of the driver outputs a different but equivalent code, how would they get converted to the same thing? – supercat Jan 20 '14 at 00:53
  • @supercat maybe your thinking I'm okay with accepting non-characters based on the above; I'm not, I would ban them. Since any attempt to hash a string with a binary hash will have to do either NFC or NFD before the encoding of string -> octets needed by the hash, that's where it is done. Any character sequence would be either (1) refused as containing something not a recognised character (2) be composed by NFC because both composed and decomposed forms were included in the same version or (3) be decomposed by NFC because the composed was added later. Either way, it would be stable. – Jon Hanna Jan 20 '14 at 09:58
  • So in other words, if a user tries to enter characters which are added after the version of Unicode the downstream Unicode processor could handle, it would be refused? That would ensure stable handling of accepted passwords, but I'm not sure how the issue should be reported to the user; few users, if told to only use characters that existed prior to e.g. May 19, 2013, would have any idea which ones those were. Another factor to consider in some scenarios would be what should happen if a user needs to log in from a machine that can't type some characters in his password. Perhaps... – supercat Jan 20 '14 at 15:44
  • ...a password-accepting system could convert everything to UTF-7 or some such representation, except without equals signs escaped, and offer a program which would show the UTF-7 equivalent of any entered string without trying to use it as a password. That would ensure that for every password there would be an ASCII-only equivalent representation. What would you think of that as an idea? – supercat Jan 20 '14 at 15:46
  • @supercat "Unrecognised character" would suffice as a message. The software could be updated though, because NFC forms are stable across Unicode versions, as long as one does not try to use a character that doesn't exist in the current version. If something has to interoperate with old technology, then that's another matter, and I did talk about interoperating with other code. Something like a website that doesn't have those restrictions, shouldn't pretend it does. – Jon Hanna Jan 20 '14 at 16:07
  • Why did you not try to write you're own *free translation* of [this](http://i.stack.imgur.com/zXGN3.jpg)? – F. Hauri - Give Up GitHub Jan 20 '14 at 22:09
-3

You should not ever store users passwords on the gateway.

The most common way is to take a hash from password, and store only this hash. In this scope, you might say that there is collision, but you should not.

The greatest way to salt is to concatinate username.password and take a hash from this combination:

username / md5sum( str(username) + str(password) )

See, md5sum not a secure anymore.

Better take a sha256:

username / sha256sum( str(username) + str(password) )

It is a sketch of solution, you might find more robust and smarter one.

  • 3
    This doesn't answer the question. It's also partly wrong and incomplete. Using the user name as a salt is bad because it will be the same in other databases. MD5 vs SHA-256 isn't relevant here, MD5 is deprecated but not broken for what it is used for here. A password hash needs unique salt and it needs to be slow. Read [How to securely hash passwords?](http://security.stackexchange.com/questions/211/how-to-securely-hash-passwords/31846#31846) – Gilles 'SO- stop being evil' Jan 23 '14 at 08:37
  • 1
    @Gilles My favourite part of this answer is that it links to md5crypt not plain MD5 when it claims that md5 isn't secure anymore. While md5crypt shouldn't be used in new systems, it's still much stronger than plain SHA256. – CodesInChaos Jan 23 '14 at 12:39