Extracting secret keys from FreeOTP

FreeOTP is a great open-source replacement for Google Authenticator, that supports TOTP and HOTP.

One of the problems I did encounter using this application is exporting the secret that is used to generate the security token, to be able to generate the same token on another device. Such an option is not available in the application, so here's how to do it.

This requires having a rooted Android device to be able to access the root file system.

1. Extract tokens.xml

Using a root file explorer browse to /data/data/org.fedorahosted.freeotp/shared_prefs. Copy tokens.xml to sdcard0 so you can open it from a computer.

2. Extract the byte encoded secret

Open tokens.xml with a web browser, you should see something like this:

<map>
    <string name="example@domain.com:SiteName">
        {"algo":"SHA1","type":"TOTP","secret":[68,-62,-15,-121,-97,110,81,58,-106,-58],"issuerExt":"example@domain.com","label":"SiteName","counter":0,"digits":6,"period":30}
    </string>
    <string name="tokenOrder">
        ["example@domain.com:SiteName"]
    </string>
</map>

The important part to grab here is the suite of numbers labeled as secret: 68,-62,-15,-121,-97,110,81,58,-106,-58

3. Convert to a hexadecimal string

These byte values now need to be converted to a hexadecimal string, I did this with the following bit of Java. You need to replace bytes with the suite of numbers labeled as secret from tokens.xml.

public class ByteConverter {

    public static void main(String[] args) {        
        byte[] bytes = new byte[]{68, -62, -15, -121, -97, 110, 81, 58, -106, -58};

        System.out.println(bytesToHex(bytes));     
    }

    public static String bytesToHex(byte[] bytes) {
        StringBuilder string = new StringBuilder();

        for(byte b : bytes) {
            string.append(String.format("%02X", b));
        }

        return string.toString();
    }
}

This should output a hexadecimal string such as 44C2F1879F6E513A96C6.

4. Convert to a base32 encoded string

Using an online hex to base32 converter (such as http://tomeko.net/online_tools/hex_to_base32.php?lang=en) paste in your Hex string and click convert, in the Output (base32) field you will have your base32 encoded secret (example: ITBPDB47NZITVFWG) for generating TOTP tokens.