Saturday, May 12, 2012
Surviving password changes with a Hash Chain
Sick and tired of having to create and memorize yet another new login password due to password expiry ? Here is an idea:
- Generate a random root password once, memorize and then destroy it
- Use a hash function (eg SHA-256) to recursively hash the root for N times, resulting in a list of hash values
H(root), H(H(root)), ...
- Every time you need a new password, pick a value from the list in the reverse order of
N, N-1, ...
- Encode (eg using ASCII-85) and truncate the value as necessary to become your new password
Sample Output:public class HashChainPassword { private static SecureRandom rand = new SecureRandom(); private static Charset UTF8 = Charset.forName("UTF-8"); public static String generate(int length) { byte[] ba = new byte[length]; rand.nextBytes(ba); String a85 = Ascii85.encodeAsString(ba); return a85.substring(0, length); } public static String nthPasswordOf(int n, String root) throws NoSuchAlgorithmException { byte[] ba = root.getBytes(UTF8); for (int i=0; i < n; i++) { MessageDigest md = MessageDigest.getInstance("SHA-256"); md.update(ba); ba = md.digest(); } String a85 = Ascii85.encodeAsString(ba); return a85.substring(0, root.length()); } public static void main(String[] args) throws NoSuchAlgorithmException { String root = HashChainPassword.generate(8); System.out.println("Root password: " + root); System.out.println("Password generation from 99th to 90th:\n"); for (int i=99; i >= 90; i--) { String s = nthPasswordOf(i, root); System.out.println(i +": " + s); } } }
Root password: H#C[Xe09 Password generation from 99th to 90th: 99: O9(kK*/l 98: NdPnLI\c 97: #.ZQ9lm& 96: KKK"`fW# 95: Wepl2msM 94: G#bitr\? 93: 0gR!CI9H 92: 9QQ#]Yn> 91: Nid.b4cg 90: WMI'e[\"