Skip to content

πŸ”“ CLI tool to decrypt backup files exported from the 2FAS Authenticator app. This application is neither affiliated with Two Factor Authentication Service, Inc. nor 2FAS.

License

Notifications You must be signed in to change notification settings

elliotwutingfeng/2fas-backup-decryptor

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

2FAS Backup Decryptor

Ruby Coveralls GitHub license

CLI tool to decrypt backup files exported from the 2FAS Authenticator app.

This application is neither affiliated with Two Factor Authentication Service, Inc. nor 2FAS.

Requirements

  • Ruby: 2.0+/3.0+, no external gems needed

  • OpenSSL: 1.0.2+/3.0+

    • In the terminal, run the following to view your Ruby interpreter's OpenSSL version

      ruby -e "require 'openssl'; puts OpenSSL::OPENSSL_LIBRARY_VERSION"
      # Example output
      # OpenSSL 3.3.2 3 Sep 2024
    • LibreSSL is not supported

  • OS: Either Windows, macOS, or Linux

Safety

Caution

This program writes the backup file content to stdout in plaintext. By default, this means the content will be displayed on the screen.

Recommended precautions:

  • Do NOT decrypt your backup file in public areas, or in the presence of untrusted persons and surveillance cameras.
  • Do NOT decrypt your backup file on a machine that you suspect to be infected by malware.
  • ENSURE that your terminal session output is not being unintentionally saved or recorded.

Example

File: test/encrypted_test.2fas

Password: example.com

# Enter the above password when prompted
ruby lib/decrypt.rb test/encrypted_test.2fas

You should get the following plaintext JSON output.

[{"name":"Deno","secret":"4SJHB4GSD43FZBAI7C2HLRJGPQ","updatedAt":1708958115316,"otp":{"label":"Mason","account":"Mason","issuer":"Deno","digits":6,"period":30,"algorithm":"SHA1","tokenType":"TOTP","source":"Link"},"order":{"position":0},"icon":{"selected":"Label","label":{"text":"DE","backgroundColor":"Brown"},"iconCollection":{"id":"a5b3fb65-4ec5-43e6-8ec1-49e24ca9e7ad"}}},{"name":"SPDX","secret":"5OM4WOOGPLQEF6UGN3CPEOOLWU","updatedAt":1708958115348,"otp":{"label":"James","account":"James","issuer":"SPDX","digits":7,"period":30,"algorithm":"SHA256","tokenType":"TOTP","source":"Link"},"order":{"position":1},"icon":{"selected":"Label","label":{"text":"SP","backgroundColor":"Red"},"iconCollection":{"id":"a5b3fb65-4ec5-43e6-8ec1-49e24ca9e7ad"}}},{"name":"Airbnb","secret":"7ELGJSGXNCCTV3O6LKJWYFV2RA","updatedAt":1708958115376,"otp":{"label":"Elijah","account":"Elijah","issuer":"Airbnb","digits":8,"period":60,"algorithm":"SHA512","tokenType":"TOTP","source":"Link"},"order":{"position":2},"icon":{"selected":"Label","label":{"text":"AI","backgroundColor":"Pink"},"iconCollection":{"id":"a5b3fb65-4ec5-43e6-8ec1-49e24ca9e7ad"}}},{"name":"Boeing","secret":"JRZCL47CMXVOQMNPZR2F7J4RGI","updatedAt":1708958115391,"otp":{"label":"Sophia","account":"Sophia","issuer":"Boeing","digits":5,"period":10,"algorithm":"SHA1","tokenType":"STEAM","source":"Link"},"order":{"position":3},"icon":{"selected":"Label","label":{"text":"BO","backgroundColor":"Brown"},"iconCollection":{"id":"a5b3fb65-4ec5-43e6-8ec1-49e24ca9e7ad"}}},{"name":"Air Canada","secret":"KUVJJOM753IHTNDSZVCNKL7GII","updatedAt":1708958401763,"otp":{"link":"otpauth://hotp/Benjamin?secret=KUVJJOM753IHTNDSZVCNKL7GII&issuer=Air%20Canada&counter=10&algorithm=SHA256&digits=8","label":"Benjamin","account":"Benjamin","issuer":"Air Canada","digits":8,"algorithm":"SHA256","counter":10,"tokenType":"HOTP","source":"Link"},"order":{"position":4},"icon":{"selected":"Label","label":{"text":"AI","backgroundColor":"Brown"},"iconCollection":{"id":"a5b3fb65-4ec5-43e6-8ec1-49e24ca9e7ad"}}}]

Other formats

You can also add the -f / --format option to print the plaintext output as csv or as a pretty CSV-like String padded with spaces.

csv

# Enter the above password when prompted
ruby lib/decrypt.rb test/encrypted_test.2fas -f csv
icon.iconCollection.id,icon.label.backgroundColor,icon.label.text,icon.selected,name,order.position,otp.account,otp.algorithm,otp.counter,otp.digits,otp.issuer,otp.label,otp.link,otp.period,otp.source,otp.tokenType,secret,updatedAt
a5b3fb65-4ec5-43e6-8ec1-49e24ca9e7ad,Brown,DE,Label,Deno,0,Mason,SHA1,,6,Deno,Mason,,30,Link,TOTP,4SJHB4GSD43FZBAI7C2HLRJGPQ,1708958115316
a5b3fb65-4ec5-43e6-8ec1-49e24ca9e7ad,Red,SP,Label,SPDX,1,James,SHA256,,7,SPDX,James,,30,Link,TOTP,5OM4WOOGPLQEF6UGN3CPEOOLWU,1708958115348
a5b3fb65-4ec5-43e6-8ec1-49e24ca9e7ad,Pink,AI,Label,Airbnb,2,Elijah,SHA512,,8,Airbnb,Elijah,,60,Link,TOTP,7ELGJSGXNCCTV3O6LKJWYFV2RA,1708958115376
a5b3fb65-4ec5-43e6-8ec1-49e24ca9e7ad,Brown,BO,Label,Boeing,3,Sophia,SHA1,,5,Boeing,Sophia,,10,Link,STEAM,JRZCL47CMXVOQMNPZR2F7J4RGI,1708958115391
a5b3fb65-4ec5-43e6-8ec1-49e24ca9e7ad,Brown,AI,Label,Air Canada,4,Benjamin,SHA256,10,8,Air Canada,Benjamin,otpauth://hotp/Benjamin?secret=KUVJJOM753IHTNDSZVCNKL7GII&issuer=Air%20Canada&counter=10&algorithm=SHA256&digits=8,,Link,HOTP,KUVJJOM753IHTNDSZVCNKL7GII,1708958401763

pretty

# Enter the above password when prompted
ruby lib/decrypt.rb test/encrypted_test.2fas -f pretty
icon.iconCollection.id                icon.label.backgroundColor  icon.label.text  icon.selected  name        order.position  otp.account  otp.algorithm  otp.counter  otp.digits  otp.issuer  otp.label  otp.link                                                                                                            otp.period  otp.source  otp.tokenType  secret                      updatedAt
a5b3fb65-4ec5-43e6-8ec1-49e24ca9e7ad  Brown                       DE               Label          Deno        0               Mason        SHA1                        6           Deno        Mason                                                                                                                          30          Link        TOTP           4SJHB4GSD43FZBAI7C2HLRJGPQ  1708958115316
a5b3fb65-4ec5-43e6-8ec1-49e24ca9e7ad  Red                         SP               Label          SPDX        1               James        SHA256                      7           SPDX        James                                                                                                                          30          Link        TOTP           5OM4WOOGPLQEF6UGN3CPEOOLWU  1708958115348
a5b3fb65-4ec5-43e6-8ec1-49e24ca9e7ad  Pink                        AI               Label          Airbnb      2               Elijah       SHA512                      8           Airbnb      Elijah                                                                                                                         60          Link        TOTP           7ELGJSGXNCCTV3O6LKJWYFV2RA  1708958115376
a5b3fb65-4ec5-43e6-8ec1-49e24ca9e7ad  Brown                       BO               Label          Boeing      3               Sophia       SHA1                        5           Boeing      Sophia                                                                                                                         10          Link        STEAM          JRZCL47CMXVOQMNPZR2F7J4RGI  1708958115391
a5b3fb65-4ec5-43e6-8ec1-49e24ca9e7ad  Brown                       AI               Label          Air Canada  4               Benjamin     SHA256         10           8           Air Canada  Benjamin   otpauth://hotp/Benjamin?secret=KUVJJOM753IHTNDSZVCNKL7GII&issuer=Air%20Canada&counter=10&algorithm=SHA256&digits=8              Link        HOTP           KUVJJOM753IHTNDSZVCNKL7GII  1708958401763

Hiding unwanted fields

When the -f / --format option is set to csv or pretty, you can use the -e / --except option to hide unwanted fields. Non-existent fields are silently ignored.

# Enter the above password when prompted
ruby lib/decrypt.rb test/encrypted_test.2fas -f pretty -e icon.iconCollection.id,icon.label.backgroundColor,icon.label.text,icon.selected,order.position,otp.link,name,otp.account,otp.source,updatedAt
otp.algorithm  otp.counter  otp.digits  otp.issuer  otp.label  otp.period  otp.tokenType  secret
SHA1                        6           Deno        Mason      30          TOTP           4SJHB4GSD43FZBAI7C2HLRJGPQ
SHA256                      7           SPDX        James      30          TOTP           5OM4WOOGPLQEF6UGN3CPEOOLWU
SHA512                      8           Airbnb      Elijah     60          TOTP           7ELGJSGXNCCTV3O6LKJWYFV2RA
SHA1                        5           Boeing      Sophia     10          STEAM          JRZCL47CMXVOQMNPZR2F7J4RGI
SHA256         10           8           Air Canada  Benjamin               HOTP           KUVJJOM753IHTNDSZVCNKL7GII

Testing

# The test suite requires Ruby 2.4 or newer
gem install bundler
bundle install
bundle exec rspec -r spec_helper