Skip to content

Instantly share code, notes, and snippets.

@tghw
Last active April 16, 2024 21:05
Show Gist options
  • 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.
@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