Google
 
Web unafbapune.blogspot.com

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:

  1. Generate a random root password once, memorize and then destroy it
  2. 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)), ...
  3. Every time you need a new password, pick a value from the list in the reverse order of
        N, N-1, ...
  4. Encode (eg using ASCII-85) and truncate the value as necessary to become your new password
As long as you can recall the root password and your current position, you can always re-generate your current password. This means you can safely use the position as your password recovery hint, if so supported by the login system.

As far as security goes, compromising an old password would not compromise any newer passwords. But the reverse is obviously not true. This means it's important that the root password is random and has sufficient size. In the example below, a size of 8 ASCII-85 encoded characters has a password space of 85^8 which is slightly more than 2^51.

Sample code:

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);
        }
    }
}
Sample Output:
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[\"


This page is powered by Blogger. Isn't yours?