Generating XKCD passwords Obviously, everyone should use a password manager to generate and store long unique random strings of characters for the vast majority of their passwords. However, one still needs to memorize a master password for their password vault! I figured that I would write my own little script to generate such a password, XKCD style:

(require '(clojure [string :as str])
         '(clojure.java [io :as io]))

(import (java.security SecureRandom)
        (java.util ArrayList
                   Collections))

(defn secure-shuffle [coll]
  (let [al (ArrayList. coll)]
    (Collections/shuffle al (SecureRandom.))
    (vec al)))

(defn lines [x]
  (with-open [rdr (io/reader x)]
    (doall (line-seq rdr))))

(defn password [n words]
  (str/join \space (take n (secure-shuffle words))))

(def filename "words.txt")

(def url "https://github.com/dwyl/english-words/raw/master/words.txt")

(if-not (.exists (io/file filename))
  (spit filename (slurp url)))

(println (password 4 (lines filename)))


Any comments on code style are very much appreciated, but I am more interested in the security of this script. To be specific, if I run this using lein-exec 0.3.6 on an Ubuntu 15.10 machine with Java 8u74 and Leiningen 2.6.1 installed, can I be confident that the resulting password has \$4 \log_2 354986 \approx 74\$ bits of entropy and is safe to use as my master password?
Obligatory link to the relevant Security question: XKCD #936: Short complex password, or long dictionary passphrase?


  can I be confident that the resulting password has 4log2354986≈74 bits of entropy and is safe to use as my master password?


That's two questions which are only partially related to each other. Let's start with the easy question first.

Is it safe to use as your master password?

A good password is:


Hard to guess.
Easy to remember.
Hard to brute-force.


You can enforce the first by making sure there's no personal data (birthday, name of your dog, name of the site, parts of your username, etc.) mentioned in the password. You got that covered.

The second issue is only tackled partially. Not all generated output makes sense or is easy to remember. However, it's likely that given enough tries a good candidate will pop-up. Keep in mind that words mentioned from categories mentioned in the previous paragraph should be avoided.

The third appears to be enforced for now, assuming you reach 74 bits of entropy as stated. I don't feel qualified to verify that, but entropy is about the selection process and not about the selected password itself. If the process has an entropy of 74 bits, it will always have 74 bits.

Computers change, brute-force methods change and what was a safe password 20 years ago may not be safe to use today. The generated passwords appear to be safe, since they take a long time to crack.