Skip to content

Instantly share code, notes, and snippets.

@monperrus
Last active December 3, 2022 17:55
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save monperrus/578395c30667581677d1ec20b7d445de to your computer and use it in GitHub Desktop.
Save monperrus/578395c30667581677d1ec20b7d445de to your computer and use it in GitHub Desktop.
Export KeePass KDBX (folders and passwords) to Bitwarden JSON
#!/usr/bin/python3
# Export KeePass folders and passwords to Bitwarden JSON
# The resulting JSON can be imported in Bitwarden, Nextcloud Passwords,
# or any password manager that supports the Bitwarden JSON format
#
# Prerequisites
# --------------
# pip3 install pykeepass
#
# Usage
# -----
# python3 export-keepass-to-bitwarden-json.py passfile.kbdx
#
# Notes
# -----
# - The Bitwarden importer in Nextcloud Passwords translates folder to tags, see https://github.com/marius-wieschollek/passwords/issues/468
#
# References
# ----------
# bitwarden importer in Nextcloud Passwords: https://github.com/marius-wieschollek/passwords/blob/master/src/js/Helper/Import/BitwardenConversionHelper.js
#
# Author: Martin Monperrus
# URL: https://gist.github.com/monperrus/578395c30667581677d1ec20b7d445de
# License: Public domain
from pykeepass import PyKeePass
import getpass
from xml.sax.saxutils import escape
import sys
import json
# load database
kp = PyKeePass(sys.argv[1], password=getpass.getpass())
def group_to_bw_folder_json(folder):
return {"id": str(folder.uuid),"name": folder.name,}
def entry_to_bw_json(entry):
if entry.title == None: entry.title = ""
if entry.username == None: entry.username = ""
if entry.password == None: entry.password = ""
# keepass has one single URL per login, while bitwarden has several
# "match":None means "default match detection"
uris = []
if entry.url: uris.append({"match":None,"uri":entry.url})
return {"id": str(entry.uuid),"type": 1, "name": entry.title,"folderId": str(entry.group.uuid),"login": {"username":entry.username, "password": entry.password, "uris":uris },"notes": entry.notes}
def export(kp):
items = []
for i in kp.entries:
items.append(entry_to_bw_json(i))
folders = []
# in keepass they are called "group", in bitwarden "folder"
for g in kp.groups:
folders.append(group_to_bw_folder_json(g))
with open('/tmp/bitwarden.json','w') as f:
json.dump({
"encrypted": False,
"folders": folders,
"items": items
},f, indent=2)
export(kp)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment