Create secure passwords, usable on US and German keyboards

Do you want to have secure passwords which are memorable and easy to type? Did you use diceware just to find out that the rate of typos when writing 6 words with 30 letters in total without seeing what you type can be aggravating — especially when you have to enter your password several times a day?

The algorithm here generates secure Letterblock passwords which are easy to type and to remember. Try it:

Length:   Password:
Get this code via npm install securepasswords
There is also a version in Python and one in wisp Scheme.

 

A major part of this article is concerned with a security estimate of the generated passwords, but firstoff, here’s an example of a password which should survive an attack leveraging all smartphones on the planet until at least 2021 at the current development speed of technology:

hXFV!4Vgf-LrgS

And here’s one which should outlast a type II civilization:

HArw-CUCG+AxRg-WAVN-5KRC*1bRq.v9Tc+SAgG,QfUc

Let’s ramp up security of passwords while making them easier to remember.

Update Also see Keylength - ECRYPT II report on key sizes. The report provides a clean overview of several different recommendations. In short: Use 128 bits. With the method shown here this is equivalent to using 5 blocks of 4 letters (length 20).

Password Generation

The method used here is pretty simple: Use blocks of four letters, chosen at random from a set of safely recognizable characters which are in the same position on German and US Keyboards. Delimit blocks by a delimiter chosen at random from another set of characters.

The sets of characters are:

For the blocks: NewBase60 without yz_. 55 letters, 5.78 bits of entropy per letter.

define qwertysafeletters "0123456789ABCDEFGHJKLMNPQRSTUVWXabcdefghijkmnopqrstuvwx"

For the delimiters: ,.! plus symbols from the numpad. 7 letters, 2.8 bits of entropy per delimiter

define delimiters ",.+-*/!"

These passwords hit the same letters on US and German keyboards, because I’m from Germany, and having to find letters like $#:\; is horrible when the keyboard reverted to US English, or when typing on the keyboard of a colleague.

Code to realize this is given in the Appendix.

Security estimate

(the code for all these calculations is available in securepassword.w from the wisp repository)

Speed of current attacks

As of 2011, a single device can do 2,800,000,000 guesses per second. Today this should be 10 billion guesses per second. According to a recovery company which sells crackers at 1.5k$, as of 2016 a zip-file can be attacked with 100,000 guesses per second. Ars Technica reports 8 billion attacks on md5 on a single device in 20131.

Codinghorror quotes2 codohale3 on the cost of buying 5 billion cracked md5 hashes per second in 2010 for just 3$ per hour. This should be around 20 billion guesses per second today.

I will from now on call 20 billion guesses per second for 3$ per hour the "strong attack" and 100,000 guesses per second the "weak attack".

8 letters + 1 delimiter: 12$ (strong attack) or till 2031 (weak attack)

A password with 8 letters and 1 delimiter (entropy 49) would on average withstand the strong attack with a single device for 4 hours, so you could buy a cracked md5-secured 8 letter + 1 delimiter password for 12$ (assuming that it was salted, otherwise you can buy all these md5’ed passwords together for around 24$).

The 8 letter and 1 delimiter password would withstand the weak attack until 2031 (when it would be cracked in one year, with a cost of 26k$), assuming doubling of processing power every two years. Cracking it in one day would be possible in 2048, paying just 72$.

(yearstillcrackable 49)
=> ((in-one-second 64.78071905112638)
    (in-one-day 31.983231667249996)
    (in-one-year 14.957750741642995))

12 letters, 2 delimiters: till 2047 (strong) or 2021 (Facebook)

A password with 12 letters and 2 delimiters (length 12, entropy 75) should withstand the strong attack until 2047 (then it would be cracked in one year), assuming doubling of processing power every two years, the weak until 2083.

For every factor of 1000 (i.e. 1024 computers), the time to get a solution is reduced by 20 years. Using every existing cell phone, the 12 letter key would be cracked by the method with 100,000 guesses per second in 2021 (within one year). Facebook could do that with Javascript, so you might want to use a longer password if your data has to be secure against the whole planet for longer than 5 years.

(yearstillcrackable 75 #:guesses/second 1.e5 #:number-of-devices 2.e9)
=> ((in-one-second 54.986013343153864)
    (in-one-day 22.188525959277467)
    (in-one-year 5.163045033670471))

28 letters, 6 delimiters: outlast human civilization

Using Landauer’s principle4, we can estimate the minimum energy needed to to check a password solution with a computer at room temperature, assuming that reversible entropy computing isn’t realized and quantum computers have to stick to Landauer’s limit: A single bit-flip requires approximately 3 Zeptojoule5 at room temperature, so we can flip 333 e18 bits per second with one Watt of Energy. Processing any information requires at least one bit-flip. Reducing the temperature to 1.e-7K (reachable with evaporative cooling) would theoretically allow increasing the bit flips per Joule to 1e30. That gives a plausible maximum of password checks per expended energy. Assuming that someone would dedicate a large nuclear powerplant with 1 Gigawatt of output to cracking your password, a 160 bit password would withstand the attack for about 23 years.

With the password scheme described here, a password with 28 letters and 6 delimiters (178 bits of entropy) should be secure for almost 6 million years in the Landauer limit at 1.e-7K, with the energy of a large nuclear power plant devoted to cracking it.

(years-to-crack-landau-limit-evaporative-cooling-nuclear-powerplant 178) => 6070231.659195759

With 24 letters and 5 delimiters it would only last about one month, though. Mind exponentials and the linear limit of the human lifespan :)

An example of a 28 letter, 6 delimiter password would be:

7XAG,isCF+soGX.f8i6,Vf7P+pG3J!4Xhf

Don’t use this one, though :)

36 letters, 8 delimiters: outlast a type II civilization

However using the total energy output of the sun (about 0.5e21 W), a 28 letter, 6 delimiter password would survive for just about 6 minutes. To reach 50 years of password survival against an attacker harnessing the energy of the sun (a type II civilization on the Kardashev scale6 devoting its whole civilization to cracking your password), you’d need 200 bits of entropy: 32 letters and 7 delimiters. A 36 letter, 8 delimiter password (230 bits of entropy) would last about 54 billion years. With that it would very likely outlast that civilization (especially if the civilization devotes all its power to crack your password) and maybe even its star. They could in theory just get lucky, though.

If you ever wanted to anger a type II civilization, encrypt their vital information with a 36 letter, 8 delimiter password like this:

HArw-CUCG+AxRg-WAVN-5KRC*1bRq.v9Tc+SAgG,QfUc

Keep in mind, though, that they might have other means to get it than brute force. And when they come for you, they will all be really angry :)

Or they might just have developed reversible computing, then all these computations are just a fun game to stretch the mind :)

Conclusion

Passwords built from delimited blocks of letters are easy to memorize and if you use 12 letters with 2 delimiters it should even withstand everything Facebook can throw at you for a few years, if you use a serious hashing algorithm.

So please make your next password look like this:

a70q-PjoL.wmew

Generate a new password (but please do not trust it, except if you copy this website and use it offline):

Length:   Password:

If you want to anger a whole type II civilization, you’ll have to go for 36 letters, though.

Appendix: The code

Javascript

Try the code:

Length:   Password:
/* @license magnet:?xt=urn:btih:0ef1b8170b3b615170ff270def6427c317705f85&dn=lgpl-3.0.txt LGPL-v3-or-Later */
var letters = "0123456789ABCDEFGHJKLMNPQRSTUVWXabcdefghijkmnopqrstuvwx";
var delimiters = ",.+-*/!";
function password(nletters) {
    var pw = "";
    for (i=0; i<nletters; i++) {
        if (i%4 == 0 && i != 0 && i != nletters){
            pw += delimiters.charAt(Math.floor(Math.random() * delimiters.length))
        }
        pw += letters.charAt(Math.floor(Math.random() * letters.length));
    }
    return pw;
}
/* @license-end */

Python

from random import choice
letters = "0123456789ABCDEFGHJKLMNPQRSTUVWXabcdefghijkmnopqrstuvwx"
delimiters = ",.+-*/!"
def password(nletters):
    """
    Generate a password with the given number of letters (not counting
    delimiters).
    """
    pw = ""
    for i in range(nletters):
        if i%4 == 0 and i != 0 and i != nletters:
            pw += choice(delimiters)
        pw += choice(letters)
    return pw

Wisp (original code)

Full code available in securepassword.w

import
    only (srfi srfi-27) random-source-make-integers
      . make-random-source random-source-randomize!
    only (srfi srfi-1) iota
    srfi srfi-42

;; newbase60 without yz_: 55 letters, 5.78 bits of entropy per letter.
define qwertysafeletters "0123456789ABCDEFGHJKLMNPQRSTUVWXabcdefghijkmnopqrstuvwx"
;; delimiters: 2.8 bits of entropy per delimiter, in the same place on main keys or the num-pad.
define delimiters ",.+-*/!"

define random-source : make-random-source
random-source-randomize! random-source

define random-integer 
       random-source-make-integers random-source

define : randomletter letters
      string-ref letters
        random-integer
          string-length letters

define : password nletters
       . "Generate a password with the given length in letters 
(not counting delimiters)."
       list->string
         append-ec (: i (iota nletters 1))
           cons : randomletter qwertysafeletters
             if : and (not (= i nletters)) : zero? : modulo i 4
                cons : randomletter delimiters
                  list
                list
Inhalt abgleichen
Willkommen im Weltenwald!



Beliebte Inhalte

sn.1w6.org news