Skip to content

Instantly share code, notes, and snippets.

@tghw
Last active April 16, 2024 21:05
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save tghw/27a4b3a237e6f62a8bb9a46670e59f61 to your computer and use it in GitHub Desktop.
Save tghw/27a4b3a237e6f62a8bb9a46670e59f61 to your computer and use it in GitHub Desktop.
Convert LastPass Authenticator JSON export to Aegis. This does not access your LastPass account or interact with any external resources for security. Please remember to delete your export files after you have imported them to Aegis as they could be used to retrieve your tokens.
@tghw
Copy link
Author

tghw commented Feb 22, 2023

To run this, download the script and run:
python lp_aegis_convert.py path/to/lastpass_auth_export.json

It will convert the LastPass Authenticator entries to the Aegis JSON format. Then, go to Import/Export -> Import in Aegis and use the Aegis file type.

You will need to transfer the files off and back onto your phone to make this work, something like Dropbox will make that easy.

@whatuser404
Copy link

Thanks for this. Worked great. Really appreciate the effort that went into this!

@Herjan
Copy link

Herjan commented Jul 27, 2023

If I may add a suggestion: your script uses issuerName from the original file as name for the new file. For me, this results in name and issuer being the same for most accounts in Aegis. So now, if I have multiple accounts for the same issuer, I just see a bunch of entries labelled e.g. "Google (Google)" in Aegis.

The userName from LastPass is added as notes, but this field is not displayed in the overview in Aegis and not searchable.

I solved it like this:

"name": account.get("userName", ""),
"issuer": account.get("originalIssuerName") if len(account.get("originalIssuerName", "")) > 0 else account.get("issuerName", ""),
"note": None,

@AlexanderMcColl
Copy link

Huge thanks to the author and to Herjan's additional improvement.
I just ran this on my Lastpass .json export to move to Aegis and it worked perfectly first time.
I hope Aegis will include Lastpass import natively soon as it looks very straightforward.

@gnofs
Copy link

gnofs commented Aug 23, 2023

I got an error due to Aegis not accepting spaces in secret strings; instead, it would just throw an error and become unusable until data storage is cleared (or the app is reinstalled). But as the spaces are just for readability anyway, they can safely be removed. Implementing both changes, by me and @Herjan, gives us the following script:

import json
import argparse
from pathlib import Path

def main(path):
    lp_json = Path(path)
    with open(lp_json) as fd:
        lp_data = json.load(fd)
    ae_entries = []
    ae_data = {
        "version": 1,
        "header": { "slots": None, "params": None },
        "db": { "version": 2, "entries": ae_entries },
    }
    for account in lp_data.get("accounts", []):
        entry = {
            "type": "totp",
            "uuid": account.get("accountID"),
            "name": account.get("userName", ""),
            "issuer": account.get("originalIssuerName") if len(account.get("originalIssuerName", "")) > 0 else account.get("issuerName", ""),
            "note": None,
            "favorite": account.get("isFavorite", False),
            "icon": None,
            "info": {
                "secret": account.get("secret").replace(" ", "") if "secret" in account else None,
                "algo": account.get("algorithm"),
                "digits": account.get("digits"),
                "period": account.get("timeStep"),
            },
        }
        ae_entries.append(entry)
    ae_json = lp_json.parent / f"aegis_{lp_json.name}"
    with open(ae_json, "w") as fd:
        json.dump(ae_data, fd)
    print(f"Converted. Export file: {ae_json}")


if __name__ == "__main__":
    parser = argparse.ArgumentParser("LastPass Authenticator to Aegis JSON Converter")
    parser.add_argument("filename", help="LastPass Authenticator JSON File")
    args = parser.parse_args()
    main(args.filename)

@tghw
Copy link
Author

tghw commented Aug 23, 2023

Thanks! I've converted this to a repo, which can be found at: https://github.com/tghw/lastpass_aegis_convert

@denisemenov
Copy link

Thank you. Your code inspired me to write an analogue in typescript for node.js. :)
https://github.com/denisemenov/lastpass-auth-export

@tghw
Copy link
Author

tghw commented Apr 16, 2024

Thank you. Your code inspired me to write an analogue in typescript for node.js. :) https://github.com/denisemenov/lastpass-auth-export

🙌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment