Passwords are one of the oldest,1 most widely used mechanisms for authenticating users – found everywhere from web apps and APIs, to operating systems and IoT devices. Other authentication methods have since become available (such as biometric logins and hardware tokens), but passwords still underpin access control for the vast majority of services.
However, using passwords alone is increasingly considered insecure. Modern best practice favours multi-factor authentication (MFA), where a password is combined with something the user has (like a phone or hardware key) or something they “are” (like a fingerprint). Relying on passwords alone leaves systems too easily vulnerable to “credential stuffing” (attackers re-using stolen passwords) and brute-force attacks.
The way we hash and store passwords has evolved significantly in the past few decades. Simple hashing algorithms like MD5 or SHA-1 are no longer considered acceptable for use in securing systems. Today, secure systems use slow, salted, key-stretching algorithms like bcrypt, scrypt, or Argon2 to make attacks computationally expensive.
Guidelines have also shifted. Prior to the late 2010s, typical advice for generating passwords was that they should:
Much of the burden was placed on users to come up with strong passwords, remember dozens of them, rotate them regularly, and never write them down.
See if you can find the password guidelines for some of the organizations you work or study at. How many of them use practices from the list above?
Of the secure design principles we’ve looked at in lectures, which one do the guidelines above violate?
By 2017, many standards bodies, such as NIST, had abandoned these practices. They resulted in users:
Tr0ub4dor&3
, which
are hard for humans to remember (which of the “o’s” was actually a
“0
”?), and are not especially resistant to cracking.Password1
,
Password2
, etc.), reusing old ones, or writing them down,
to deal with frequent requests to change passwords.In short, as the comic XKCD explains, these practices trained people to use passwords that are hard for humans to remember, but easy for computers to guess.
Instead, modern best practices advocate that for user accounts2
The UK National Cyber Security Centre (NCSC) provides a helpful page of advice for system owners on modern best practices, which is worth reading through.
Service accounts
Note that the above advice only applies to user accounts used by humans. Credentials are also needed by so-called service accounts. These are accounts used by automated tools (such as scripts, bots, or background services) in order to authenticate themselves, typically to other systems.
For instance, if your computer uses a backup program which backs your files up to cloud storage, then it will need some sort of credential – an account name and password, or equivalent3 – for the cloud provider (such as Backblaze or Carbonite) who provides that backup storage.
For service accounts, different considerations apply, since often:
OWASP calls accounts like these “Non-Human Identities”, and notes that best practice is still to ensure the credentials they use regularly expire (or are rotated).
See if you can answer the following questions, after reviewing the material on cryptography in the lectures.
Suppose in the CITS3007 SDE you create the MD5 hash of some password, using a command like:
$ printf mypassword | md5sum
In what format is the hash displayed? How large is the hash, in bytes? How would you write it in C syntax?
What is the purpose of salting passwords, when creating a password hash?
Look up Wikipedia to refresh your memory of what a hash collision is. Explain why hash collisions necessarily occur. That is, why must there always be two different plaintexts that have the same hash value?
You can use your lab time to work on the CITS3007 project. You may wish to discuss your project tests and code design with other students or the lab facilitators (although the actual code you submit must be your own, individual work).
Roman soldiers used “watchwords” to identify each other (especially at night, to distinguish allies from potential enemies). These watchwords would often be changed daily for security. See Polybius’s Histories, translated by E.S. Shuckburgh (London: Macmillan, 1889), p 487, available at Project Gutenberg.↩︎
See section 5.1.1, “Memorized secrets” of NIST standard SP 800-63B↩︎
Sometimes service accounts will authenticate themselves using a password-like value. But often a preferred approach is for them to use a public-private key pair. When the service account needs to authenticate itself to another system, it sends an authentication request; the foreign system provides a randomly generated value (a “challenge”) which the service account then must encrypt with its private key (producing a “response”), proving that it is who it claims to be. This is basically the same method the Git program uses to authenticate itself on your behalf to GitHub if you use an SSH key pair to authenticate – it’s called a challenge–response protocol.↩︎