Recovering Google Authenticator Keys from iOS Backups
Update 2017-12-31: As reported on the comments, this is no longer working under iOS 10/11 due to the inability of the iphone-dataprotection code to decrypt keychains from these newer versions.
Keep an eye on this reported issue, in case itâs ever fixed.
There are also reported issues with installing m2crypto, see this stackoverflow page.
Update 2015-10-11: Iâve updated the results based on great infro from Jay Zhuang in the comments about how to decode the final data element.
This was previously entitled âTrying to Extract Google Authenticator Keys from iOS Backupsâ but has now been updated to reflect successful key recovery.
Update 2015-12-07: As pointed out in the comments, it looks like newer versions of Google Authenticator store keys in a way that canât be retrieved from iOS Backups (only restored to the same device). This only affects new keys added to the app - older keys are still able to be retrieved.
Verified on:
- OS X 10.10
- Python 2.7
- iOS 9.0.2
A mess-up from Google that had an iOS update of Google Authenticator in 2013 wipe out previously stored accounts, as well as some problems restoring backups onto a new iOS device recently got me thinking that there has to be a way to get the account keys out of iOS backups. Iâve previously written an article on how to do the same thing on Android. Google Accounts now pretty easily let you switch devices, but as using Google Authenticator for 2 factor authentication gets more and more popular there are still cases where you need to be able to get at those keys.
Google Authenticator uses a time based one-time-password system that relies on a âshared keyâ. This is all you really need, since the rest is purely algorithmic. Details: https://github.com/google/google-authenticator If you have that key, you can easily get a new Google Autheenticator app installation (or various other apps that support the Time-based One-time Password TOTP Algorithm in RFC 6238) configured to generate codes for your account.
iOS backups contain all the data from your apps. Google Authenticator stores your Google Authenticator keys in the iOS Keychain rather than as application level data. iOS backups have the Keychain encrypted with a key which you canât get from your iOS device (the UID-Key) without jail-breaking. Iâm not going down that path here. However, IF youâre smart and had iTunes encrypt your backups, then Apple decides to use that password to encrypt not only your various application data files, but your Keychain data too. This makes it easier if you want to restore onto another device, like a new phone. That means if we have an encrypted iOS backup we can get at the Keychain location where Google Authenticator stores the keys.
Note - if youâre using iCloud Backups this wonât work for you. It doesnât store the protected keychain info.
Requirements
- Encrypted backup of iOS device (if you didnât encrypt your local iTunes backups, or youâre using iCloud backup, you are out of luck)
- Mac running OS X 10.10 Yosemite (you can do this in another OS or version, but youâre on your own)
- Python with pip
Step 1 - Finding your backup
Backups are stored in
/Users/YOUR_USER_NAME/Library/Application\ Support/MobileSync/Backup/
One of the long hex string directories contained there will be the backup you want. How to determine which one (if you have multiple iOS devices)? Open up iTunes, go into Preferences -> Devices then you should see the names of each of your devices, and the date of latest backup. That date/time should correspond to the modified date of one of the directories in your backups directory listed above.
Step 2 - Decrypting your backup
Download the tools referenced here: https://github.com/dinosec/iphone-dataprotection. These used to live on Google Code, but that is being discontinued.
In order to do this youâll need to get some dependencies installed. I use Homebrew to install python, then pip to manage the dependencies. If you donât have pip please lookup some python tutorials.
pip install M2crypto construct progressbar pycrypto
In the iphone-dataprotection package, youâll find a python_scripts directory.
Since these scripts are referencing /usr/bin/python in the first line, itâs helpful to run them explicitly with âpython scriptname.pyâ to ensure your updated homebrew python (and the dependencies which you just used pip to install dependencies) is used.
Use the script âbackup_tool.pyâ to decrypt your backup. Use the hex directory of your backup as the only argument. Youâll need the password you set up when first setting iTunes to encrypt your iOS backups.
python ./backup_tool.py PATH_TO_BACKUP
If it works, youâll now have an _extract directory which contains the decrypted backup files.
References: http://www.securitylearn.net/tag/decrypt-iphone-backup-keychain/
Step 3 - Decrypt your Keychain
Take a look in your _extract directory at âKeychainDomain/keychain-backup.plistâ. This file contains all the encrypted elements from your iOS keychain. If you do a text search on the reference value you found in the previous stepâs plist file, it should appear in this file too.
Use another script from the iphone-dataprotection toolkit called âkeychain_tool.pyâ. This one takes 2 arguments. First is your âxxx_extract/KeychainDomain/keychain-bakup.plistâ the second is your âxxx_extract/Manifest.plistâ file. Use the -d option to have it display your keychain data.
python keychain_tool.py -d "PATH_TO_extract/KeychainDomain/keychain-backup.plist" "PATH_TO_extract/Manifest.plist"
Look at that! Thereâs a lot of decrypted data on your screen now. Pipe it out to a file so you can inspect it properly. Search for âcom.google.otp.authenticationâ. Thatâs in the first column âServiceâ - and youâll see in the Account column the name of your account. Look in the Data column. This is where the magic is. Wait a sec - the value is truncated. How come?
Well it looks like for purposes of making the output easy to read, the utility libraries truncate that field at position 20. Letâs fix that.
Find and open the keychain.py
file, go down to line 148 (may change if the source is updated) and change
to
That should give us enough space to see the full value. Run it again, and indeed, now it shows a longer value.
You should see a value like this:
>38ec20dfd3e65e8c14d5cac9a313b15991a3c6b7.
Step 4 - Convert your key into base32
(taken from comments below, thanks again Jay Zhuang)
You will need to convert your shared key value into base32 for entry into the Google Authenticator app. I used this online javascript converter to go from hex to ASCII: http://tomeko.net/online_tools/hex_to_base32.php?lang=en
Determine whether you have a hex or ASCII code - and convert it to base32
-
If the data column started with â>â, the key is represented in hex, convert it to base32. ex.
>9123aabbccdd81925566
=>SER2VO6M3WAZEVLG
-
Otherwise, the seed is represented in ASCII, convert it to binary then base32. ex.
AQ67YYR488
=>41513637595952343838
=>IFITMN2ZLFJDIOBY
Notes - I havenât seen one of these ASCII keys in looking through mine in order to verify, only the hex style keys
Step 5 - Transfer the key into a new Google Authenticator installation
Once you have your key converted to base32, you can enter this value straight into Google Authenticator by choosing the âManual entryâ option, or get a new QR code generated to scan into the app.
If you want to generate a new QR code and scan it into your app, you can use a generator such as http://dan.hersam.com/tools/gen-qr-code.html or try and create one manually from an OTP URI.
Whichever method you choose, I highly recommend you change your shared key with whatever accounts you are using. The step of using a conversion tool, or generating a new QR code, as well as just having an unencrypted file on your machine with all the keychain data from your phone all represent ways you could be giving away your key data.
Leave a Comment