commit 4598a9b6567d19d2f054d08ef6056791143e5457
parent 225aaf7ce1333fb41267a8a6c76c56daa0fd8388
Author: Santtu Lakkala <inz@inz.fi>
Date: Sat, 25 Jul 2020 11:40:15 +0000
Exporting tokens from FreeOTP
Diffstat:
1 file changed, 35 insertions(+), 0 deletions(-)
diff --git a/posts/exporting-tokens-from-freeotp.md b/posts/exporting-tokens-from-freeotp.md
@@ -0,0 +1,35 @@
+# Exporting tokens from FreeOTP
+
+After using FreeOTP on a single device for a while, I came to the conclusion that it would be safer to store the tokens on multiple devices, in case one is out of battery or out-of-arms-reach.
+
+I didn't find any option from the UI to do it, so I checked the data over adb, and as the tokens were stored as JSON-in-XML, I whipped up a quick perl script to convert the data to a list of otpauth:// URIs.
+
+ #!/usr/bin/perl -w
+
+ use XML::LibXML;
+ use JSON;
+ use MIME::Base32;
+ use URI::Encode qw/uri_encode/;
+
+ my $p = XML::LibXML->new();
+ my $d = $p->load_xml(string => join '', <<>>);
+ my $j = JSON->new();
+
+ for ($d->findnodes('/map/string')) {
+ my $l = $_->findvalue('@name');
+ next if $l eq 'tokenOrder';
+ my $d = $j->decode($_->findvalue('.'));
+ $d->{secret} = encode_base32(join('', map {
+ chr(($_ + 256) % 256)
+ } @{$d->{'secret'}}));
+ print "otpauth://" . lc($d->{'type'}) . "/" .
+ uri_encode($l) . "?" .
+ join("&", map { $_ . "=" . uri_encode($d->{$_}) } keys %$d) .
+ "\n";
+ }
+
+The output of which can be then be fed to qrencode or similar to get tokens added to another device.
+
+I used:
+<pre>adb shell su -c 'cat /data/data/org.fedorahosted.freeotp/shared_prefs/tokens.xml''./otp.pl'while read u; do qrencode -o - $u ' display -; done</pre>
+to view the codes one-by-one. (Note: this method needs rooted device, it may be possible to do it without, but didn't look for one).