A slightly different way to generate strong, memorable passwords

It’s a good idea to avoid remembering passwords – the more passwords you need to remember, the more tempting it is to re-use them. Ideally you should use a password manager like Bitwarden to store almost all of your passwords.

But of course you can’t store your Bitwarden password in Bitwarden, so it’s still necessary to memorize at least that one password. You’ll probably also need to memorize your disk encryption password and your user account password for your computer. So how do you choose these passwords to be secure and memorable?

Entropy

If you’re interested in computer security, you have probably seen the “Correct Horse Battery Staple” XKCD comic. It advocates choosing four random common words as your passphrase, instead of doing the traditional password generation black magic, because these passwords can be harder to guess and easier to remember. It’s a good illustration of the concept of “entropy”: In the context of security, entropy is a measure of how difficult your password is to guess, and it depends on how you chose the password.

For example, If you choose your password by flipping a coin 10 times, and adding a “1” if you get heads or a “0” if you get tails, your password has 10 bits of entropy. That means that an attacker who knew your decision procedure would have to guess, on average, 2^(10-1) passwords in order to successfully guess the one you chose. Adding one bit of entropy (one coin flip) to your password doubles the number of guesses required. It’s a good idea to incorporate as many truly random choices into your password as possible, to ensure that it’s really unpredictable.

Diceware

A respected way to generate secure passwords is by using the Diceware word list. You sit there rolling dice for a few minutes to choose random words. If you want your password to have 128 bits of entropy (enough for essentially all purposes), you can generate one by randomly choosing ten words from the Diceware list. And if you roll a password with N words in it, you’ll end up with N * log2(6^5) bits of entropy.

I’ve used this method in the past, and it works well. But the passwords I get are often difficult to remember: The words don’t have any semantic structure, and it’s not always easy to come up with mnemonics for lists of ten words.

The Reordered Diceware method

Instead of choosing N words in order and trying to remember them in the order you rolled them, you might try reordering the words you roll, to give them a more memorable structure. Unfortunately you lose some bits when doing this, and it’s important to take that into account. Pessimistically, your password using this method could have as few as log2(6^5 choose N) bits of entropy, or 107 bits for 10 words. To guarantee more than 128 bits of entropy, now your password needs to contain 13 words. And you’re still stuck using all the words you rolled, which limits how memorable your password will be.

Reordered Diceware with discards

I’ve started generating passwords in the following way:

First, roll 15 Diceware words. Then, choose your favorite 13 of those 15 words, and discard the other 2. Put those 13 words into any order you want, with punctuation separating them. This password can be very memorable, because you had a lot of options for just how it should be put together. And while the precise entropy is difficult to calculate, I believe it is at least 127.75 bits no matter how you choose the discards and ordering. For more details about how to compute this lower bound for different password sizes, check out Marcello Herreshoff’s solution here.

In addition to being strong, I’ve found that passwords generated this way are quite memorable, compared to the pure Diceware method.

Port Knocking Better

I am not a security expert; I am just some guy. The usual caveats apply. 

Generally, it is a good idea to have fewer ports open on your server. When you have ports open, you leak information about what services are running on your server, and any misconfigured or vulnerable programs listening on those ports can become targets.

Normally, a server must have open ports in order to do its job, at least when you don’t know in advance which addresses it needs to serve. Port knocking is a technique that allows you to have zero open ports on a server, while still allowing connections from trusted clients.

Port Knocking

In the simplest case, port knocking does what it sounds like: You disallow all connections to all ports on your server, using your favorite firewall. Then, you configure a simple daemon to watch for a particular sequence of “knocks”: packets sent to closed ports on the server. When it sees the appropriate sequence of knocks from some IP address, it tells your firewall to (temporarily) allow connections from that address, on whatever port your service is listening on (typically port 22, for ssh). This is like if your speakeasy had a “secret knock” that must be performed before the bouncer opens the door. Trusted clients know the secret knock, and so when connecting to your server they use the knock sequence before attempting to connect.

Avoiding Replays

As with real-life secret knocks, though, this technique is susceptible to replay attacks: if someone is able to hear the secret knock, they can repeat it easily. A person snooping on your traffic may be able to see that you sent a suspicious sequence of packets before successfully connecting, and then use the same sequence themselves.

Some knocking daemons, such as knockd, can mitigate this with a feature that lets you use “one time sequences”: A list of sequences that must be used in the appropriate order, and are then discarded. This works well when only one client needs to connect to the server: That client can keep track of the same list of knock sequences, and discard ones that it has used.

If multiple clients need to connect to the server, each client can get its own list.

But a problem with this approach is that one must generate sequence lists long enough to ensure that the client will be able to connect as many times as they wish. In principle this may not be too difficult; if you plan to connect fifty times a day for a hundred years, this amounts to less than 100 MiB of configuration. In practice I’m not entirely sure how knockd would deal with such a large list.

Using TOTP

An alternative would be to use a scheme like the TOTP system you (hopefully) use for two-factor authentication on your phone. In this scheme, the server and clients use the current time to agree on a knock sequence. The server gets a secret that’s shared with the client, and whenever the server sees a knock sequence corresponding to the current OTP value, it opens the port (and discards that value).

There are at least two implementations of this idea: one by Akshay Shah and Swapnil Kumbhar, and another by Javier Junquera Sánchez. Neither of these solutions looks very polished, but they exist as proofs-of-concept.

I haven’t looked hard at the code for either of these implementations, so I can’t recommend them. There are various pitfalls involved here; the most important is that the TOTP-generated sequence must be discarded after use, to avoid fast replay attacks. And one may want to use different TOTP keys for each client or user (to ensure that multiple clients aren’t racing for the same code if they need to connect at similar times). I suspect that the above implementations don’t deal nicely with at least one of these issues, though again I haven’t looked at them in detail.

Shah and Kumbhar’s solution above uses knockd’s one time sequences feature, but is forced to restart knockd to reload its configuration whenever the keys change. Ideally it would be great if knockd incorporated a TOTP-based configuration option, or had some other method of avoiding replays than long lists of knock sequences.