Update 2021-03-27: Good news, it seems KeepassXC 2.7.0 learned to import Firefox timestamps. 😀
Go to about:logins
in Firefox.
Click on the three dots in the top right corner, select “Export Logins…” and save your passwords info a CSV file (e.g. exported_firefox_logins.csv).
There’s one complication: Firefox will save dates as Unix timestamps (with millisecond resolution) which KeePassXC doesn’t understand, so we’ll have to help it out.
Save the following script into a file (e.g. firefox_csv_date_fix.py).
#!/usr/bin/env python3
#
# Author: Riyad Preukschas <riyad@informatik.uni-bremen.de>
# License: Mozilla Public License 2.0
# SPDX-License-Identifier: MPL-2.0
import csv
import sys
from datetime import datetime
def main():
if len(sys.argv) != 2:
print("Usage: {} <exported_firefox_logins.csv>".format(sys.argv[0]), file=sys.stderr)
exit(1)
csv_file_name = sys.argv[1]
with open(csv_file_name, 'rt') as f:
# field names will be determined from first row
csv_reader = csv.DictReader(f)
# read all rows in one go
rows = list(csv_reader)
# add new columns with Iso-formatted dates
for row in rows:
row['timeCreatedIso'] = datetime.fromtimestamp(int(row['timeCreated'])/1000).isoformat()
row['timeLastUsedIso'] = datetime.fromtimestamp(int(row['timeLastUsed'])/1000).isoformat()
row['timePasswordChangedIso'] = datetime.fromtimestamp(int(row['timePasswordChanged'])/1000).isoformat()
# write out the updated rows
csv_writer = csv.DictWriter(sys.stdout, fieldnames=rows[0].keys())
csv_writer.writeheader()
csv_writer.writerows(rows)
if __name__ == '__main__':
main()
Call it giving it the path of the exported_firefox_logins.csv file and redirect the output into a new file:
python3 ./firefox_csv_date_fix.py ./exported_firefox_logins.csv > ./fixed_firefox_logins.csv
It will add new columns (named: old column name + “Iso”) with the dates converted to the ISO 8601 format KeePassXC wants.
We can now use the fixed_firefox_logins.csv file to import the logins into KeePassXC.
Select Database -> Import -> CSV File...
from the menu.
It will ask you to create a new database. Just do it you can get the data into your default database later (e.g. call it firefox_logins.kdbx for now).
In the import form select “First line has field names” and match up KeePassXC’s fields with the columns from the CSV:
KeePassXC Field | Firefox CSV Column | Notes |
Group | Not Present | |
Title | url | Firefox doesn’t have a title field so we use the URL for it. |
Username | username | |
Password | password | |
URL | url | |
Notes | httpRealm | I’m not sure how KeePassXC deals with HTTP authentication. There’s no special field for it, so I decided to keep it in the Notes field. |
TOTP | Not Present | |
Icon | Not Present | |
Last Modified | timePasswordChangedIso | the “Iso” part is important! |
Created | timeCreatedIso | the “Iso” part is important! |
Have a look at the preview at the bottom. Does the data look sane? 🤨
Sadly KeePassXC doesn’t let us import Firefox’s timeLastUsedIso
field into its Accessed
field. 😑
All your imported Logins will be inside the “Root” group. I’d suggest creating a new group (e.g. “Firefox Import”) and moving all imported Logins into it.
You can now open your default database and use the Database -> Merge From Database ...
menu item, select the firefox_logins.kdbx file to include it’s contents into the current database. You’ll see a new “Firefox Imports” group show up.
You can now move the single entries into the appropriate groups if you want (e.g. “KeePassXC-Browser Passwords” if you use the browser extension).