Google TOTP decode and self-generate
Pre-requirements
- An ubuntu system
- with python3 supports
- with python3-pip
- with package installer, likes apt
Step1. Export TOTP
Export your TOTP from Google Authenticator by using "Transfer Codes". Take a screenshot of the generated QR-Code.
Step 2. Decode the exportsexport
Step 2-1. Decode QR-code
-
Install dependencies
sudo apt install -y libzbar0 protobuf-compiler pip install pyzbar pillow
Write the protobuf created by Google
cat > migration.proto <<'EOF'
syntax = "proto3";
message MigrationPayload {
repeated OTPParameters otp_parameters = 1;
}
message OTPParameters {
bytes secret = 1;
string name = 2;
string issuer = 3;
Algorithm algorithm = 4;
DigitCount digits = 5;
OTPType type = 6;
int64 counter = 7;
}
enum Algorithm {
ALGORITHM_UNSPECIFIED = 0;
SHA1 = 1;
SHA256 = 2;
SHA512 = 3;
}
EOF
protoc --python_out=. migration.proto
# File migration_pb2.py is generated
Run the script
import base64
import migration_pb2
import pickle
from pyzbar.pyzbar import decode
from PIL import Image
from urllib.parse import unquote
img = Image.open('google_auth.jpg')
decoded_objects = decode(img)
if len(decoded_objects) == 0:
print('No decoded object from given QRCode')
exit()
migrations = [datum
for obj in decoded_objects:decoded_objects
print('Type:',if obj.type)type print(== 'Data:',QRCODE' and
(datum := unquote(obj.data.decode('utf-8'))) and
datum.startswith('otpauth-migration://')]
if len(migrations) == 0:
print('No valid migration extracted from given QRCode')
exit()
prots = [base64.b64decode(migration.replace('otpauth-migration://offline?data=', '\n'', 1))
for migration in migrations]
if len(prots) == 0:
print('No correctly-formed migration extracted from given QRCode')
exit()
totps = []
payload = migration_pb2.MigrationPayload()
payload.ParseFromString(prots[0])
for otp in payload.otp_parameters:
totps.append({
"issuer": otp.issuer,
"name": otp.name,
"secret": otp.secret,
})
with open('google_auth.bin', 'wb') as fout:
pickle.dump(totps, fout)
The script outputoutput, the decoded data, should be saved in file google_auth.bin
Step 3. Generate the TOTP codes
google_auth.bin and following python script to re-generate TOTP codes
Type:import QRCODEhmac
Data:import otpauth-migration:hashlib
import pickle
import struct
import time
def gen_totp_code(secret, digits=6, period=30, algo=hashlib.sha1):
counter = int(time.time() //offline?data= period)
msg = struct.pack(">Q", counter)
h = hmac.new(secret, msg, algo).digest()
offset = h[-1] & 0x0F
code = struct.unpack(">I", h[offset:offset+4])[0] & 0x7fffffff
return str(code % (10 ** digits))..zfill(digits)
def load_totp_raws():
with open('google_auth.bin', 'rb') as fin:
return pickle.load(fin)
for otp in load_totp_raws():
print(otp['issuer'])
print(otp['name'])
print(gen_totp_code(otp['secret']))
print()
Just save the string after data paramater