Enforcing Complex Passwords In Manjaro

Manjaro has a weird password-quality setup. The password-quality functionality is provided by the libpwquality package, which provides a PAM plugin named pwquality.so and configuration at /etc/security/pwquality.conf . However, once installed it seems to still not be referenced by the PAM configuration and will not be applied to password changes.

Before making changes, open a root prompt. You will make your changes here and have a place to restore your configuration from if you break anything. Make a backup of /etc/pam.d/system-auth .

Make sure you have the libpwquality package installed.

Open /etc/pam.d/system-auth . There are PAM configurations that deal with authenticating the user and PAM configurations that deal with updating passwords. Look for the password-setting configuration block; those lines will have “password” as the module-type (first column):

-password  [success=1 default=ignore]  pam_systemd_home.so
password   required                    pam_unix.so          try_first_pass nullok shadow
password   optional                    pam_permit.so

Insert the line for pam_pwquality.so above (always above) pam_unix.so, and update the configuration for pam_unix.so to:

password requisite pam_pwquality.so retry=3
password required pam_unix.so try_first_pass nullok shadow use_authtok

The change will apply immediately, though you probably will not see a difference with the default password-quality configuration settings.

Make your desired changes to /etc/security/pwquality.conf . We recommend the following settings:

minlen = 10
dcredit = -1
ucredit = -1
lcredit = -1
ocredit = -1

Open the shell for a nonprivileged account that you would like to use to test password changes and proceed to test the password-quality options that you enabled in order to ensure they work as expected. If you made a mistake, fix them in the root console that you should still have open.

Important note: Unless you have enabled “enforce_for_root” in the password-quality or PAM configuration, you will only see advisory warnings for nonconformant passwords when running as root. You will still be able to set any password you’d like.

Using HMACs instead of Plain Hashes for Security

We all know that everyone should be storing passwords as cryptographic hashes (SHA256, for example), these days. The Internet has now been around too long for people to not know this. In addition, engineers that write communications code will often employ “message authentication codes” (“MACs”). These are hashes calculated over data that is passed back and forth from the remote system, and can be used to verify that various data hasn’t been modified (preventing “man in the middle” attacks).

However, it is much lesser known that hashes used in the manner that they often are widely vulnerable to attack. For example (in Python):

from hashlib import sha256

salt = b"3qk4yfbgql"
message = b"some data"
salted_data = salt + message
digest_ = sha256(salted_data).hexdigest()

This is no good. Our hash functions are referred to as “iterative hash functions”. In other words, they calculate the hash by iterating, one chunk at a time, through the cleartext. They suffer from what Bruce Schneier refers to as the “length extension bug”. In other words, it’s trivial for a third-party to append data to the message, even though it’s salted, and calculate another, completely valid, MAC. If you move the salt to the end of the message, there are different problems.

Enter the HMAC (“keyed hashed message authentication code”). An HMAC tool will take the salt, data, and a hash function, and do this: hash(salt + hash(salt + message))

import hmac
from hashlib import sha256

salt = b"3qk4yfbgql"
message = b"some data"
hmac_ = hmac.new(salt, message, sha256)
digest_ = hmac_.hexdigest()

Problem solved (for now).