Skip to content

Instantly share code, notes, and snippets.

@YoRyan
Created February 25, 2018 02:28
Show Gist options
  • Save YoRyan/0a331e30c12feb4c47bd8731ac736b61 to your computer and use it in GitHub Desktop.
Save YoRyan/0a331e30c12feb4c47bd8731ac736b61 to your computer and use it in GitHub Desktop.
KeePass to PasswordSafe password database converter
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Use me:
# 1. Export to CSV from KeePass
# 2. $ ./keepass2pwsafe.py <keepass.csv >passwordsafe.txt
# 3. Import from Plain Text in PasswordSafe, use the default delimiters
# Tested with KeePassXC 2.2.4 and PasswordSafe 1.02.1 for Linux
__author__ = "Ryan Young"
__email__ = "rayoung@utexas.edu"
__license__ = "public domain"
import csv
import sys
NEWLINE = '\n'
DELIMITER = '\t'
LINE_DELIMITER = '»'
def read_keepass(fd):
class KeepassDialect(csv.Dialect):
delimiter = ','
doublequote = True
escapechar = None
lineterminator = NEWLINE
quotechar = '"'
quoting = csv.QUOTE_ALL
skipinitialspace = False
strict = True
creader = csv.reader(fd, dialect=KeepassDialect)
fields = next(creader) # first line = header
records = []
for data in creader:
records.append(dict(zip(fields, data)))
return records
def write_pwsafe(records, fd):
fd.write(DELIMITER.join(['Group/Title', 'Username', 'Password', 'URL', 'Notes']))
fd.write(NEWLINE)
fd.flush()
escape = lambda f: f.replace(NEWLINE, LINE_DELIMITER)
for record in records:
# group/title
groups = [g.replace('.', LINE_DELIMITER) for g in record['Group'].split('/')[1:]]
group_title = '%s.%s' % ('.'.join(groups), record['Title'].replace('.', LINE_DELIMITER))
fd.write(group_title)
fd.write(DELIMITER)
# username
fd.write(escape(record['Username']))
fd.write(DELIMITER)
# password
if record['Password'] == '':
fd.write(LINE_DELIMITER) # field is mandatory
else:
fd.write(escape(record['Password']))
fd.write(DELIMITER)
# url
fd.write(escape(record['URL']))
fd.write(DELIMITER)
# notes
if record['Notes'] == '':
fd.write(LINE_DELIMITER) # field is mandatory
else:
fd.write(escape(record['Notes']))
fd.write(NEWLINE)
fd.flush()
entries = read_keepass(sys.stdin)
write_pwsafe(entries, sys.stdout)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment