Last active
March 3, 2025 20:01
-
-
Save talk2bryan/d6e1f9cf960a9a88c6e85db98f509dee to your computer and use it in GitHub Desktop.
KeePassXC CSV export file to ProtonPass Generic CSV import file
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Usage: python keepassxc_to_protonpass_import.py | |
# | |
# Description: This script converts a KeePassXC CSV export to a ProtonPass | |
# Generic CSV import. | |
# | |
# The script assumes that the KeePassXC CSV file has the following headers: | |
# Group, Title, Username, Password, URL, Notes, TOTP, Icon, Last Modified, Created | |
# | |
# The script assumes that the ProtonPass CSV file has the following headers: | |
# name, url, email, username, password, note, totp, vault | |
# | |
import csv | |
PROTONPASS_HEADERS = [ | |
"name", | |
"url", | |
"email", | |
"username", | |
"password", | |
"note", | |
"totp", | |
"vault", | |
] | |
KEEPASSXC_HEADERS = [ | |
"Group", | |
"Title", | |
"Username", | |
"Password", | |
"URL", | |
"Notes", | |
"TOTP", | |
"Icon", | |
"Last Modified", | |
"Created", | |
] | |
def map_keepassxc_to_protonpass(keepassxc_row: dict) -> dict: | |
"""Converts a KeePassXC row to a ProtonPass row. | |
Args: | |
keepassxc_row (dict): A row from a KeePassXC CSV file. | |
Returns: | |
dict: A row corresponding to a ProtonPass CSV file. | |
""" | |
protonpass_row = { | |
"name": keepassxc_row["Title"], | |
"url": keepassxc_row["URL"], | |
"email": keepassxc_row["Username"] if "@" in keepassxc_row["Username"] else "", | |
"username": keepassxc_row["Username"], | |
"password": keepassxc_row["Password"], | |
"note": keepassxc_row["Notes"], | |
"totp": keepassxc_row["TOTP"], | |
"vault": keepassxc_row["Group"], | |
} | |
return protonpass_row | |
def convert_keepassxc_to_protonpass(input_filepath: str, output_filepath: str) -> None: | |
"""Converts a KeePassXC CSV export to a ProtonPass Generic CSV import.""" | |
with open(input_filepath, mode="r", newline="", encoding="utf-8") as infile, open( | |
output_filepath, mode="w", newline="", encoding="utf-8" | |
) as outfile: | |
reader = csv.DictReader( | |
infile, | |
quotechar='"', | |
delimiter=",", | |
quoting=csv.QUOTE_ALL, | |
skipinitialspace=True, | |
) | |
writer = csv.DictWriter( | |
outfile, | |
fieldnames=PROTONPASS_HEADERS, | |
quotechar='"', | |
delimiter=",", | |
quoting=csv.QUOTE_ALL, | |
) | |
writer.writeheader() | |
for row in reader: | |
# Ignore rows with Group "Recycle Bin" | |
# Important! - Comment out the following lines if you want to include deleted entries | |
# if row["Group"] == "Recycle Bin": | |
# continue | |
# Remove "Root/" from the group name | |
if row["Group"].startswith("Root/"): | |
row["Group"] = row["Group"][5:] | |
protonpass_row = map_keepassxc_to_protonpass(row) | |
writer.writerow(protonpass_row) | |
# Example usage | |
INPUT_FILE = "/home/username/keepassxc.csv" | |
OUTPUT_FILE = "/home/username/protonpass.csv" | |
convert_keepassxc_to_protonpass(input_filepath=INPUT_FILE, output_filepath=OUTPUT_FILE) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment