Make an iTunes encrypted backup which contains the Keychain, where Tofu stores all the tokens.
You'll need irestore for decrypting the keychain. Use it like this:
irestore iPhone dumpkeys dump.txt
This will ask for your encryption password, then get you a dump.txt containing some json.
Run this "oneliner":
cat dump.txt \
| jq -r '.General[] | select(.agrp == "QG8TM5XJ84.com.calleerlandsson.Tofu") | .v_Data' \
| while IFS= read -r line; do \
echo "$line" \
| base64 --decode \
| dd bs=1 skip=1 status=none \
| plistutil -i - -f xml \
| xmllint --noout --xpath '/plist/dict' - ; done \
| awk 'BEGIN{print "<totps>"} {print} END{print "</totps>"}' >totps.xml
This produces an XML of all your saved TOTP secrets.
I didn't bother implementing a proper parser, but here's a PowerShell script that can convert the default type TOTP:
Function Invoke-Base32Encode {
param(
[Parameter(Mandatory = $true)][byte[]] $ByteArray
)
$byteArrayAsBinaryString = -join $ByteArray.ForEach{
[Convert]::ToString($_, 2).PadLeft(8, '0')
}
# Pad the binary string to a multiple of 5
$remainder = $byteArrayAsBinaryString.Length % 5
if ($remainder -ne 0) {
$padding = 5 - $remainder
$byteArrayAsBinaryString += ('0' * $padding)
}
$Base32String = [regex]::Replace($byteArrayAsBinaryString, '.{5}', {
param($Match)
'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567'[[Convert]::ToInt32($Match.Value, 2)]
})
Return $Base32String
}
([xml](Get-Content totp.xml)).totps.dict | ForEach-Object {
$a = $_.array;
$label = $a.string[1];
$issuer = $a.string[2];
$secretb64 = $a.data.Trim();
$secret = [System.Convert]::FromBase64String($secretb64);
$secretb32 = Invoke-Base32Encode $secret;
"otpauth://totp/${issuer}:${label}?secret=$secretb32&issuer=$issuer";
}
cat totp.txt | xargs -I{} qrencode -t UTF8 "{}"
s/powershell/python/
: