diff --git a/example_export.txt b/example_export.txt index bdc6619..022072e 100644 --- a/example_export.txt +++ b/example_export.txt @@ -2,3 +2,10 @@ # Secret key: 7KSQL2JTUDIS5EF65KLMRQIIGY # otpauth://totp/pi@raspberrypi?secret=7KSQL2JTUDIS5EF65KLMRQIIGY&issuer=raspberrypi otpauth-migration://offline?data=CjUKEPqlBekzoNEukL7qlsjBCDYSDnBpQHJhc3BiZXJyeXBpGgtyYXNwYmVycnlwaSABKAEwAhABGAEgACjr4JKK%2B%2F%2F%2F%2F%2F8B + +# otpauth://totp/pi@raspberrypi?secret=7KSQL2JTUDIS5EF65KLMRQIIGY +otpauth-migration://offline?data=CigKEPqlBekzoNEukL7qlsjBCDYSDnBpQHJhc3BiZXJyeXBpIAEoATACEAEYASAAKLzjp5n4%2F%2F%2F%2F%2FwE%3D + +# otpauth://totp/pi@raspberrypi?secret=7KSQL2JTUDIS5EF65KLMRQIIGY&issuer=raspberrypi +# otpauth://totp/pi@raspberrypi?secret=7KSQL2JTUDIS5EF65KLMRQIIGY +otpauth-migration://offline?data=CigKEPqlBekzoNEukL7qlsjBCDYSDnBpQHJhc3BiZXJyeXBpIAEoATACCjUKEPqlBekzoNEukL7qlsjBCDYSDnBpQHJhc3BiZXJyeXBpGgtyYXNwYmVycnlwaSABKAEwAhABGAEgACiQ7OOa%2Bf%2F%2F%2F%2F8B diff --git a/extract_otp_secret_keys.py b/extract_otp_secret_keys.py index 28274bb..8dc8d89 100644 --- a/extract_otp_secret_keys.py +++ b/extract_otp_secret_keys.py @@ -2,10 +2,10 @@ # # Usage: # 1. Export the QR codes from "Google Authenticator" app -# 2. Read QR codes with QR code reader +# 2. Read QR codes with QR code reader (e.g. with a second device) # 3. Save the captured QR codes in a text file. Save each QR code on a new line. (The captured QR codes look like "otpauth-migration://offline?data=...") # 4. Call this script with the file as input: -# python extract_otp_secret_keys.py -q example_export.txt +# python extract_otp_secret_keys.py -p example_export.txt # # Requirement: # The protobuf package of Google for proto3 is required for running this script. @@ -57,12 +57,8 @@ arg_parser.add_argument('--printqr', '-p', help='print QR code(s) as text to the arg_parser.add_argument('infile', help='file or - for stdin (default: -) with "otpauth-migration://..." URLs separated by newlines, lines starting with # are ignored') args = arg_parser.parse_args() +if args.saveqr or args.printqr: from qrcode import QRCode verbose = args.verbose -saveqr = args.saveqr -printqr = args.printqr - -if saveqr or printqr: - from qrcode import QRCode # https://stackoverflow.com/questions/40226049/find-enums-listed-in-python-descriptor-for-protobuf def get_enum_name_by_number(parent, field_name): @@ -84,6 +80,7 @@ def print_qr(data): qr.add_data(data) qr.print_tty() +i = j = 0 for line in (line.strip() for line in fileinput.input(args.infile)): if verbose: print(line) if line.startswith('#') or line == '': continue @@ -97,13 +94,15 @@ for line in (line.strip() for line in fileinput.input(args.infile)): data = base64.b64decode(data_encoded) payload = generated_python.google_auth_pb2.MigrationPayload() payload.ParseFromString(data) - if verbose: print(payload) + i += 1 + if verbose: print('\n{}. Payload Line'.format(i), payload, sep='\n') # pylint: disable=no-member - i = 0 for otp in payload.otp_parameters: - i += 1 - print('\nName: {}'.format(otp.name)) + j += 1 + if verbose: print('\n{}. Secret Key'.format(j)) + else: print() + print('Name: {}'.format(otp.name)) secret = convert_secret_from_bytes_to_base32_str(otp.secret) print('Secret: {}'.format(secret)) if otp.issuer: print('Issuer: {}'.format(otp.issuer)) @@ -112,14 +111,12 @@ for line in (line.strip() for line in fileinput.input(args.infile)): if otp.type == 1: url_params['counter'] = otp.counter if otp.issuer: url_params['issuer'] = otp.issuer otp_url = 'otpauth://{}/{}?'.format('totp' if otp.type == 2 else 'hotp', quote(otp.name)) + urlencode(url_params) - if saveqr: - if verbose: print(otp_url) + if verbose: print(otp_url) + if args.printqr: + print_qr(otp_url) + if args.saveqr: if not(path.exists('qr')): mkdir('qr') pattern = rcompile(r'[\W_]+') file_otp_name = pattern.sub('', otp.name) file_otp_issuer = pattern.sub('', otp.issuer) - if not(file_otp_issuer): print_qr(otp_url) - if file_otp_issuer: save_qr(otp_url, 'qr/{}-{}-{}.png'.format(i, file_otp_name, file_otp_issuer)) - if printqr: - if verbose: print(otp_url) - print_qr(otp_url) + save_qr(otp_url, 'qr/{}-{}{}.png'.format(j, file_otp_name, '-' + file_otp_issuer if file_otp_issuer else ''))