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?