README
¶
Authy Migration Toolset
This is a Go library that allows you to access your Authy TOTP tokens.
It was created to facilitate migrating from Authy to Token2 hardware tokens (including Molto2 multi-profile TOTP hardware token) or other TOTP Apps.
Please note that this tool only migrates non-Authy-hosted accounts (the ones that are generating 7-digit OTP with 10/20 seconds interval). The tool is intended to migrate "standard" TOTP profiles : 6 or 8 digits, 30 seconds (Authy app supports only 30 seconds TOTP profiles in addition to its native accounts).
Applications
authy-export
This program will enrol itself as an additional device on your Authy account and export all of your TOTP tokens in Key URI Format.
Installation
Pre-built binaries are available from the page.
Alternatively, it can be compiled from source, which requires Go 1.12 or newer:
go get github.com/token2/authy-migration/cmd/authy-export
To use it:
- Run
authy-export
- The program will prompt you for your phone number country code (e.g. 1 for United States) and your phone number. This is the number that you used to register your Authy account originally.
- If the program identifies an existing Authy account, it will send a device registration request using the
push
method. This will send a push notification to your existing Authy apps (be it on Android, iOS, Desktop or Chrome), and you will need to respond that from your other app(s). - If the device registration is successful, the program will save its authentication credential (a random value) to
$HOME/authy-go.json
for further uses. Make sure to delete this file and de-register the device after you're finished. - If the program is able to fetch your TOTP encrypted database, it will prompt you for your Authy backup password. This is required to decrypt the TOTP secrets for the next step.
- The program will dump all of your TOTP tokens in a file in the same folder: a .txt file which can be used for importing to Molto2 directly, or HTML file with QR codes, which you can use to import to other applications.
Third-party modules
If you wish to compile this from the source code, make sure you add the following modules to your Go enviroment
golang.org/x/crypto/ssh/terminal
github.com/skip2/go-qrcode
LICENSE
See LICENSE
Trademark Legal Notice
All product names, logos, and brands are property of their respective owners. All company, product and service names used in this website are for identification purposes only. Use of these names, logos, and brands does not imply endorsement
Documentation
¶
Index ¶
- type AuthenticatorApp
- type AuthenticatorAppsResponse
- type AuthenticatorToken
- type AuthenticatorTokensResponse
- type Client
- func (c Client) CheckDeviceRegistration(ctx context.Context, userID uint64, requestID string) (DeviceRegistrationStatus, error)
- func (c Client) CompleteDeviceRegistration(ctx context.Context, userID uint64, pin string) (CompleteDeviceRegistrationResponse, error)
- func (c Client) QueryAuthenticatorApps(ctx context.Context, userID uint64, deviceID uint64, deviceSeed string) (AuthenticatorAppsResponse, error)
- func (c Client) QueryAuthenticatorTokens(ctx context.Context, userID uint64, deviceID uint64, deviceSeed string) (AuthenticatorTokensResponse, error)
- func (c Client) QueryDevicePrivateKey(ctx context.Context, deviceID uint64, deviceSeed string) (DevicePrivateKeyResponse, error)
- func (c Client) QueryUser(ctx context.Context, countryCallingCode int, phone string) (UserStatus, error)
- func (c Client) RequestDeviceRegistration(ctx context.Context, userID uint64, via ViaMethod) (StartDeviceRegistrationResponse, error)
- type CompleteDeviceRegistrationResponse
- type DevicePrivateKeyResponse
- type DeviceRegistrationStatus
- type StartDeviceRegistrationResponse
- type UserStatus
- type ViaMethod
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AuthenticatorApp ¶
type AuthenticatorApp struct { ID string `json:"_id"` // Display name of the token Name string `json:"name"` SerialID int `json:"serial_id"` Version int `json:"version"` AssetsGroup string `json:"assets_group"` AuthyID uint64 `json:"authy_id"` // The Device Secret Seed (hex-encoded). It is the TOTP // secret that protects the authenticated endpoints. SecretSeed string `json:"secret_seed"` // How many digits in the TOTP Digits int `json:"digits"` }
AuthenticatorApp is embedded in AuthenticatorAppsResponse
func (AuthenticatorApp) Token ¶
func (a AuthenticatorApp) Token() (string, error)
Token produces the base32-encoded TOTP token backing this app. It has a period of 10.
type AuthenticatorAppsResponse ¶
type AuthenticatorAppsResponse struct { // Display to user Message string `json:"message"` // Active encrypted authenticator apps AuthenticatorApps []AuthenticatorApp `json:"apps"` // Recently deleted, but not removed encrypted authenticator apps Deleted []AuthenticatorApp `json:"deleted"` // Whether this request succeeded Success bool `json:"success"` }
AuthenticatorAppsResponse is the response from: https://api.authy.com/json/users/{User_ID}/devices/{Device_ID}/apps/sync
type AuthenticatorToken ¶
type AuthenticatorToken struct { // In the Authy app, this is the visual icon type of this token AccountType string `json:"account_type"` // How many digits this TOTP token is Digits int `json:"digits"` // The encrypted TOTP seed EncryptedSeed string `json:"encrypted_seed"` // User-nominated name for the token Name string `json:"name"` // Purpose not known OriginalName string `json:"original_name"` // Purpose not known PasswordTimestamp uint64 `json:"password_timestamp"` // The salt used to encrypt the EncryptedSeed Salt string `json:"salt"` // The ID of this token UniqueID string `json:"unique_id"` }
AuthenticatorToken is embedded in AuthenticatorTokensResponse
func (AuthenticatorToken) Decrypt ¶
func (t AuthenticatorToken) Decrypt(passphrase string) (string, error)
Decrypt returns the base32-encoded seed for this TOTP token, decrypted by passphrase.
func (AuthenticatorToken) Description ¶
func (t AuthenticatorToken) Description() string
Description returns OriginalName if not empty, otherwise Name, otherwise `Token-{UniqueID}`.
type AuthenticatorTokensResponse ¶
type AuthenticatorTokensResponse struct { // Display to user Message string `json:"message"` // Active encrypted authenticator token AuthenticatorTokens []AuthenticatorToken `json:"authenticator_tokens"` // Recently deleted, but not removed encrypted authenticator tokens Deleted []AuthenticatorToken `json:"deleted"` // Whether this request succeeded Success bool `json:"success"` }
AuthenticatorTokensResponse is the response from: https://api.authy.com/json/users/{User_ID}/authenticator_tokens?api_key={API_Key}&otp1={OTP_1}&otp2={OTP_2}&otp3={OTP_3}&device_id={Device_ID
type Client ¶
Client provides API interaction with the Authy API. See NewClient()
func (Client) CheckDeviceRegistration ¶
func (c Client) CheckDeviceRegistration(ctx context.Context, userID uint64, requestID string) (DeviceRegistrationStatus, error)
CheckDeviceRegistration fetches the status of the device registration request (requestID) for the nominated Authy User ID (userID). This should be polled with a timeout.
func (Client) CompleteDeviceRegistration ¶
func (c Client) CompleteDeviceRegistration(ctx context.Context, userID uint64, pin string) (CompleteDeviceRegistrationResponse, error)
CompleteDeviceRegistration completes the device registration process for the nominated Authy User ID (userID) and PIN (from the DeviceRegistrationStatus)
func (Client) QueryAuthenticatorApps ¶
func (c Client) QueryAuthenticatorApps(ctx context.Context, userID uint64, deviceID uint64, deviceSeed string) (AuthenticatorAppsResponse, error)
QueryAuthenticatorApps fetches the encrypted Authy App tokens for userID, authenticating using the deviceSeed (hex-encoded).
func (Client) QueryAuthenticatorTokens ¶
func (c Client) QueryAuthenticatorTokens(ctx context.Context, userID uint64, deviceID uint64, deviceSeed string) (AuthenticatorTokensResponse, error)
QueryAuthenticatorTokens fetches the encrypted TOTP tokens for userID, authenticating using the deviceSeed (hex-encoded).
func (Client) QueryDevicePrivateKey ¶
func (c Client) QueryDevicePrivateKey(ctx context.Context, deviceID uint64, deviceSeed string) (DevicePrivateKeyResponse, error)
QueryDevicePrivateKey fetches the PKCS#1 private key for the nominated device ID, using the known device secret TOTP seed from CompleteDeviceRegistrationResponse.
func (Client) QueryUser ¶
func (c Client) QueryUser(ctx context.Context, countryCallingCode int, phone string) (UserStatus, error)
QueryUser fetches the status of an Authy user account.
func (Client) RequestDeviceRegistration ¶
func (c Client) RequestDeviceRegistration(ctx context.Context, userID uint64, via ViaMethod) (StartDeviceRegistrationResponse, error)
RequestDeviceRegistration begins a new device registration for an Authy User account, via the nominated mechanism.
type CompleteDeviceRegistrationResponse ¶
type CompleteDeviceRegistrationResponse struct { Device struct { // The Device ID ID uint64 `json:"id"` // The Device Secret Seed (hex-encoded, 32-bytes). It is the TOTP // secret that protects the authenticated endpoints. SecretSeed string `json:"secret_seed"` // Purpose not known. APIKey string `json:"api_key"` // Purpose not known, but probably whether this device is being // re-installed. Reinstall bool `json:"reinstall"` } `json:"device"` // The Authy User ID AuthyID uint64 `json:"authy_id"` }
CompleteDeviceRegistrationResponse is the response from: https://api.authy.com/json/users/16480/devices/registration/complete
type DevicePrivateKeyResponse ¶
type DevicePrivateKeyResponse struct { Message string `json:"message"` PrivateKey string `json:"private_key"` Success bool `json:"success"` }
DevicePrivateKeyResponse is the response from https://api.authy.com/json/devices/{Device_ID}/rsa_key?api_key={API_Key}&&otp1={OTP_1}&otp2={OTP_2}&otp3={OTP_3}&device_id={DEVICE_ID}
func (DevicePrivateKeyResponse) AsPrivateKey ¶
func (r DevicePrivateKeyResponse) AsPrivateKey() (*rsa.PrivateKey, error)
AsPrivateKey parses the PEM private key in PrivateKey
type DeviceRegistrationStatus ¶
type DeviceRegistrationStatus struct { // pending, accepted, rejected, ?? Status string `json:"status"` // PIN is required to complete the device registration PIN string `json:"pin"` // Whether this status request was successful, distinct to whether the // registration process is complete. Success bool `json:"success"` }
DeviceRegistrationStatus is the response from: https://api.authy.com/json/users/{User_ID}/devices/registration/{Request_ID}/status?api_key={API_Key}&locale=en-GB&signature=b54ff1b646b207ff2da50ecb9a0bc2c770a1357b04278c8dd402f835db2824f4
type StartDeviceRegistrationResponse ¶
type StartDeviceRegistrationResponse struct { // Message to display to the user upon receiving this response Message string `json:"message"` // The Request ID is used to poll the status of the device registration process RequestID string `json:"request_id"` // Purpose unclear ApprovalPIN int `json:"approval_pin"` // The ViaMethod Provider string `json:"provider"` // Whether the device registration request was accepted. // This is distinct to the device registration being successful/complete. Success bool `json:"success"` }
StartDeviceRegistrationResponse is the response from: https://api.authy.com/json/users/{User_ID}/devices/registration/start
type UserStatus ¶
type UserStatus struct { // Presumably, force device validation over HTTP rather than // allowing a phone call or SMS. ("Over the top"). ForceOTT bool `json:"force_ott"` // How many devices are registered to this Authy user DevicesCount int `json:"devices_count"` // Authy User ID AuthyID uint64 `json:"authy_id"` // Presumably some kind of opaque status string Message string // Whether this request was successful Success bool }
UserStatus is the response from: https://api.authy.com/json/users/{Country}-{Phone}/status
func (UserStatus) IsActiveUser ¶
func (us UserStatus) IsActiveUser() bool
IsActiveUser reports whether this is an an active, registered Authy user.