Skip to content

sentryco/GAMigration

Repository files navigation

Tests

GAMigration

Google authenticator migration

Description:

Enables you to extract two-factor authentication secret keys from QR codes exported by Google Authenticator

Prerequisites

  • Swift 5.0 or later
  • iOS 17 or macOS 14 or later

Problem

  • Obtain the precise proto3 schema used by Google Authenticator to ensure compatibility.
  • Create a specialized Proto3Parser class designed to interpret this specific schema.
  • Implement comprehensive error handling to address parsing exceptions and edge cases.

Solution

  • Efficient data extraction from strings using a ProtoBuf wrapper.
  • Support for exporting data in the widely used OTP format.
  • Robust error handling, ensured through comprehensive unit testing.

Features

  • Efficiently parses and decrypts Google Authenticator migration payloads.
  • Supports a wide variety of OTP types and cryptographic algorithms.
  • Provides comprehensive error handling to gracefully handle a broad range of edge cases.
  • Utilizes rigorous unit testing to validate functionality and ensure the solution's integrity.

Installation

To integrate GAMigration into your Xcode project using Swift Package Manager, specify it in your Package.swift file:

.package(url: "https://github.com/sentryco/GAMigration", branch: "main")

Note

Google Authenticator uses a specific format for exporting OTP accounts via QR codes. The QR code contains a URL with the following structure: otpauth-migration://offline?data=

Usage Example

let stringFromGoogleAuthApp = "otpauth-migration://offline?data=CjEKCkhlbGxvId6tvu8SGEV4YW1wbGU6YWxpY2VAZ29vZ2xlLmNvbRoHRXhhbXBsZTAC"
if let decrypted = try? GAExtractor.parseMigrationURI(input: stringFromGoogleAuthApp), let firstOTP = decrypted.first {
    print("Type: \(firstOTP.type)") // output: type: .totp
    print("Algorithm: \(firstOTP.algorithm)") // output: algorithm: .unspecified
    print("Name: \(firstOTP.name)") // output: name: "Example:[email protected]"
    print("Secret: \(firstOTP.secret)") // output: secret: "JBSWY3DPEHPK3PXP"
    print("Issuer: \(firstOTP.issuer)") // output: issuer: "Example"
    print("Counter: \(firstOTP.counter)") // output: counter: 0
    print("Digits Raw Value: \(firstOTP.digitsRawValue)") // output: digitsRawValue: 0
} else {
    print("An error occurred or no OTPs were found.")
}

Important

Implement proper error handling in the calling code to handle edge cases

Dependencies:

The following dependencies are used in the package:

These dependencies are managed by the Swift Package Manager (SPM) and are defined in the Package.swift file of the project.

Note

Use Swift's built-in URL and Data handling methods for parsing the initial parts of the QR code

What Are Protocol Buffers?

Protocol buffers are Google’s language-neutral, platform-neutral, extensible mechanism for serializing structured data – think XML, but smaller, faster, and simpler. You define how you want your data to be structured once, then you can use special generated source code to easily write and read your structured data to and from a variety of data streams and using a variety of languages.

Additional Considerations:

  • Multiple QR codes: If there are many accounts, Google Authenticator may split them into multiple QR codes. You'll need to handle this by processing each QR code separately
  • Security: Ensure that you handle the extracted secret keys securely, as they are sensitive information
  • Compatibility: This method specifically works with Google Authenticator's export format. Other authenticator apps may use different formats

Important

Ensure that you're following security best practices when dealing with sensitive authentication data.

References:

Discussions:

Todo:

  • try base64 and proto3

About

Google authenticator migration

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages